Как исправить «Ошибка типа: не удается преобразовать значение в тип DType TensorFlow»?

#python #tensorflow #machine-learning #image-processing #generative-adversarial-network

Вопрос:

Я попытался создать GAN (Генеративную состязательную сеть) для набора данных рукописных чисел, я столкнулся с проблемой, связанной с ошибкой типа данных тензора.

  1. Строка 78, I используется «tf.cast» для преобразования всех изображений в float32.
  2. Для потерь генератора и дискриминатора я использовал «tf.потери.Бинарная перекрестная энтропия».

Я не понимаю, где происходит ошибка.

ВОТ ПОЛНЫЙ КОД

 import tensorflow as tf
import matplotlib.pyplot as plt
import scipy.io as sio
from sklearn.model_selection import train_test_split
import numpy as np

(train, label), (test, label_test) = tf.keras.datasets.mnist.load_data()

train_images = train.reshape(train.shape[0], 28, 28, 1)
train_images = (train_images-127.5)/127.5

BUFFER_SIZE = train.shape[0]
BATCH_SIZE = 100
train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)

def discriminator():
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Conv2D(7, (3,3), padding='same', input_shape=(28, 28, 1)))
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.LeakyReLU(0.1))
    model.add(tf.keras.layers.Dense(128, activation='relu'))
    model.add(tf.keras.layers.Dense(1))
    return model

dis_model = discriminator()
disc_opt = tf.optimizers.Adam()

def discriminator_loss(y_pred_real, y_pred_fake):
    real = tf.sigmoid(y_pred_real)
    fake = tf.sigmoid(y_pred_fake)
    fake_loss = tf.losses.binary_crossentropy(tf.ones_like(y_pred_real), y_pred_real)
    real_loss = tf.losses.binary_crossentropy(tf.zeros_like(y_pred_fake), y_pred_fake)
    return fake_loss real_loss

def generator():
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(7*7*256, input_shape=(100,)))
    model.add(tf.keras.layers.BatchNormalization())
    model.add(tf.keras.layers.Reshape((7, 7, 256)))
    model.add(tf.keras.layers.Conv2DTranspose(128, (3, 3), padding='same'))
    model.add(tf.keras.layers.BatchNormalization())
    model.add(tf.keras.layers.Conv2DTranspose(64, (3,3), strides=(2,2), padding='same'))
    model.add(tf.keras.layers.BatchNormalization())
    model.add(tf.keras.layers.Conv2DTranspose(1, (3,3), strides=(2,2), padding='same'))
    return model

gen_model = generator()
gen_opt = tf.optimizers.Adam()

def generator_loss(fake_pred):
    loss = tf.sigmoid(fake_pred)
    fake_loss = tf.losses.BinaryCrossentropy(tf.zeros_like(fake_pred), fake_pred)
    return fake_loss

def train_steps(images):
    fake_noise = np.random.randn(BATCH_SIZE, 100).astype('float32')
    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
        generated_images = gen_model(fake_noise)

        fake_output = dis_model(generated_images)
        real_output = dis_model(images)

        gen_loss = generator_loss(fake_output)
        disc_loss = discriminator_loss(real_output, fake_output)

        gen_gradient = gen_tape.gradient(gen_loss, gen_model.trainable_variables)
        disc_gradient = disc_tape.gradient(disc_loss, dis_model.trainable_variables)

        gen_opt.apply_gradients(zip(gen_gradient, gen_model.trainable_variables))
        disc_opt.apply_gradients(zip(disc_gradient, dis_model.trainable_variables))

        print('disc_loss: ', np.mean(disc_loss))
        print('gen_loss: ', np.mean(gen_loss))

def train(dataset, epoch):
    for j in range(epoch):
        for images in dataset:
            images = tf.cast(images, tf.dtypes.float32)
            train_steps(images)


train(train_dataset, 2)

 

ПРОИСХОДИТ ОШИБКА

 Traceback (most recent call last):
  File "D:/GANs_handwritten/model.py", line 81, in <module>
    train(train_dataset, 2)
  File "D:/GANs_handwritten/model.py", line 78, in train
    train_steps(images)
  File "D:/GANs_handwritten/model.py", line 66, in train_steps
    gen_gradient = gen_tape.gradient(gen_loss, gene.trainable_variables)
  File "C:UsersDevanshuAppDataLocalProgramsPythonPython38libsite-packagestensorflowpythoneagerbackprop.py", line 1047, in gradient
    if not backprop_util.IsTrainable(t):
  File "C:UsersDevanshuAppDataLocalProgramsPythonPython38libsite-packagestensorflowpythoneagerbackprop_util.py", line 30, in IsTrainable
    dtype = dtypes.as_dtype(dtype)
  File "C:UsersDevanshuAppDataLocalProgramsPythonPython38libsite-packagestensorflowpythonframeworkdtypes.py", line 649, in as_dtype
    raise TypeError("Cannot convert value %r to a TensorFlow DType." %
TypeError: Cannot convert value <tensorflow.python.keras.losses.BinaryCrossentropy object at 0x000001E5190BE850> to a TensorFlow DType.
 

Ответ №1:

Как следует из официальных документов по реализации DCGAN в TensorFlow, сначала создайте BinaryCrossentropy объект, а затем вызовите этот объект с y помощью и y_pred .

Во-первых, инициализируйте BinaryCrossentropy объект,

 # This method returns a helper function to compute cross entropy loss
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
 

Затем вызовите cross_entropy объект с y помощью и y_pred ,

 def generator_loss(fake_output):
    return cross_entropy(tf.ones_like(fake_output), fake_output)
 

В вашем коде замените,

 def generator_loss(fake_pred):
    loss = tf.sigmoid(fake_pred)
    fake_loss = tf.losses.BinaryCrossentropy(tf.zeros_like(fake_pred), fake_pred)
    return fake_loss
 

с,

 def generator_loss(fake_pred):
    loss = tf.sigmoid(fake_pred)
    fake_loss = tf.keras.losses.BinaryCrossentropy()(tf.zeros_like(fake_pred), fake_pred)
    return fake_loss
 

Внесите ту же поправку в метод discriminator_loss ,

 def discriminator_loss(y_pred_real, y_pred_fake):
    real = tf.sigmoid(y_pred_real)
    fake = tf.sigmoid(y_pred_fake)
    fake_loss = tf.keras.losses.BinaryCrossentropy()(tf.ones_like(y_pred_real), y_pred_real)
    real_loss = tf.keras.losses.BinaryCrossentropy()(tf.zeros_like(y_pred_fake), y_pred_fake)
    return fake_loss real_loss