#python #tensorflow
#python #tensorflow
Вопрос:
Пытаюсь построить модель Tensorflow, в которой мои данные содержат 70 функций. Вот настройка моего первого слоя:
tf.keras.layers.Dense(units=50, activation='relu', input_shape=(None,70)),
Установка формы ввода на (None,70)
показалась мне лучшей, поскольку я использую нейронную сеть прямой связи, где каждая «строка» данных уникальна. Я использую размер пакета (на данный момент) размером 10. Должна ли моя форма ввода измениться на (10,70)
??
Я пробовал с оригиналом (None, 70)
и получил ошибку:
WARNING:tensorflow:Model was constructed with shape (None, None, 70) for input Tensor("dense_33_input:0", shape=(None, None, 70), dtype=float32), but it was called on an input with incompatible shape (10, 70).
TypeError: Input 'y' of 'Mul' Op has type float64 that does not match type float32 of argument 'x'.
Совершенно запутался в том, что именно происходит не так с input_shape
as (None, 70)
, похоже, подходит лучше всего. Любая помощь очень ценится.
Редактировать: хотел добавить воспроизводимый пример для большего контекста. Извините за длину. Это воспроизведение [этого примера] [1], чтобы лучше соответствовать моим текущим данным (не изображениям).
Вариационная модель автоэнкодера
class VAE(tf.keras.Model):
def __init__(self, latent_dim):
super(VAE, self).__init__()
self.latent_dim = latent_dim
self.encoder = tf.keras.Sequential(
[
tf.keras.layers.Dense(units=50, activation='relu', input_shape=(70,)),
tf.keras.layers.Dense(latent_dim latent_dim), #No activation
])
self.decoder = tf.keras.Sequential(
[
tf.keras.layers.Dense(units=50, activation='relu', input_shape=(latent_dim,)),
tf.keras.layers.Dense(units=70),
])
@tf.function
def sample(self, eps=None):
if eps is None:
eps = tf.random.normal(shape=(100, self.latent_dim))
return self.decode(eps, apply_sigmoid=True)
def encode(self, x):
mean, logvar = tf.split(self.encoder(x), num_or_size_splits=2, axis=1)
return mean, logvar
def reparameterize(self, mean, logvar):
eps = tf.random.normal(shape=mean.shape)
return eps * tf.exp(logvar * .5) mean
def decode(self, z, apply_sigmoid=False):
logits = self.decoder(z)
if apply_sigmoid:
probs = tf.sigmoid(logits)
return probs
return logits
[1]: https://www.tensorflow.org/tutorials/generative/cvae
Функция оптимизации и потери
optimizer = tf.keras.optimizers.Adam(1e-4)
def log_normal_pdf(sample, mean, logvar, raxis=1):
log2pi = tf.math.log(2. * np.pi)
return tf.reduce_sum(
-.5 * ((sample - mean) ** 2. * tf.exp(-logvar) logvar log2pi), axis=raxis)
def compute_loss(model, x):
mean, logvar = model.encode(x)
z = model.reparameterize(mean, logvar)
x_logit = model.decode(z)
cross_ent = tf.nn.sigmoid_cross_entropy_with_logits(logits=x_logit, labels=x)
logpx_z = -tf.reduce_sum(cross_ent, axis=[1])
logpz = log_normal_pdf(z, 0, 0)
logqz_x = log_normal_pdf(z, mean, logvar)
return -tf.reduce_mean(logpx_z logpz - logqz_x)
@tf.function
def train_step(model, x, optimizer):
with tf.GradientTape() as tape:
loss = compute_loss(model, x)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
Поезд
X = tf.random.uniform((100,70))
y = tf.random.uniform((100,))
ds_train = tf.data.Dataset.from_tensor_slices((X, y))
tf.random.set_seed(1)
train = ds_train.shuffle(buffer_size=len(X))
train = train.batch(batch_size=10, drop_remainder=False)
epochs = 5
latent_dim = 2
model = VAE(2)
for epoch in range(1, epochs 1):
start_time = time.time()
for i, (train_x, train_y) in enumerate(train):
train_step(model, train_x, optimizer)
end_time = time.time()
loss = tf.keras.metrics.Mean()
for i, (test_x, test_y) in enumerate(ds_test):
loss(compute_loss(model, test_x))
elbo = -loss.result()
display.clear_output(wait=False)
print('Epoch: {}, Test set ELBO: {}, time elapse for current epoch: {}'
.format(epoch, elbo, end_time - start_time))
Комментарии:
1. Не могли бы вы, пожалуйста, определить
X_train
иy_train
?2. Извините … должно быть исправлено сейчас.
y
в этом примере нет необходимости.3. Я не могу воспроизвести эту ошибку в вашем примере, и я столкнулся с другими ошибками. Не могли бы вы исправить свой пример? Попробуйте запустить его в новом интерпретаторе Python (переменные еще не определены). Без примера будет сложно помочь.
4. @jakub только что внес незначительные изменения в
y
и ось в reduce_sum. Должно быть с той же ошибкой, что и у меня5. Спасибо. Можете ли вы попробовать изменить
logpz = log_normal_pdf(z, 0., 0.)
наlogpz = log_normal_pdf(z, 0., 0.)
? Это приведет к тому, что эти нули будут плавающими вместо целых чисел. Я столкнулся с ошибкой, котораяtf.exp
не может принять int32.
Ответ №1:
input_shape
Не должно включать измерение пакета. Используйте input_shape=(70,)
.
tf.keras.layers.Dense(units=50, activation='relu', input_shape=(70,))
Вы можете установить размер пакета при вызове model.fit(..., batch_size=10)
. Смотрите документацию по tf.keras.Model.fit
.
В исходном сообщении была еще одна ошибка из-за передачи int32
значения tf.math.exp
. Эта строка должна гласить
logpz = log_normal_pdf(z, 0., 0.)
чтобы устранить эту ошибку. Обратите внимание на 0.
значения, которые оцениваются как значения с плавающей точкой вместо целых чисел.
Комментарии:
1. Все еще получаю последнюю ошибку:
TypeError: Input 'y' of 'Mul' Op has type float64 that does not match type float32 of argument 'x'.
Могу поделиться дополнительным кодом, если это полезно…2. Да, пожалуйста, обновите свой пост минимальным, воспроизводимым примером.
3. Только что сделал … дайте мне знать ваши мысли. Спасибо