Ошибка значения tensorflow при связывании содержимого данных - невозможно передать значение формы (1, 1) для tensor 'placeholder_1: 0',

Этот пост связан с вопросом следующий. Приведенный выше код взят из принятого ответа.

Сама программа работает нормально как есть, но если бы я только изменил значения данных, предоставленных из

df = pd.DataFrame({'Temperature': [183, 10.7, 24.3, 10.7],
                   'Weight': [8, 11.2, 14, 11.2],
                   'Size': [3.97, 7.88, 11, 7.88],
                   'Property': [0,1,2,0]})

к

df = pd.DataFrame({'Temperature': [0,0,0,0],
                   'Weight': [1,2,3,4],
                   'Size': [1,2,3,4],
                   'Property': [1,1,1,1]})

Я получаю следующую ошибку при выполнении кода

ValueError: Cannot feed value of shape (1, 1) for Tensor 'Placeholder_1:0', which has shape '(?, 3)'

Конструктивно ничего особо не изменилось, поэтому меня очень смущает эта ошибка. Странно то, что изменение значений данных может вызвать или не вызвать эту проблему. Я пробовал разные версии TF, включая последнюю, и всегда возникает одна и та же проблема.

Кто-нибудь знает, что мне не хватает? Полный пример кода следует ниже.

import tensorflow as tf
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder

df = pd.DataFrame({'Temperature': [183, 10.7, 24.3, 10.7],
                   'Weight': [8, 11.2, 14, 11.2],
                   'Size': [3.97, 7.88, 11, 7.88],
                   'Property': [0,1,2,0]})


df.Property = df.Property.shift(-1)
print ( df.head() )
# parameters
time_steps = 1
inputs = 3
outputs = 3

df = df.iloc[:-1,:]

df = df.values

train_X = df[:, 1:]
train_y = df[:, 0]

scaler = MinMaxScaler(feature_range=(0, 1))    
train_X = scaler.fit_transform(train_X)

train_X = train_X[:,None,:]

onehot_encoder = OneHotEncoder()
encode_categorical = train_y.reshape(len(train_y), 1)
train_y = onehot_encoder.fit_transform(encode_categorical).toarray()

learning_rate = 0.001
epochs = 500
batch_size = int(train_X.shape[0]/2)
length = train_X.shape[0]
display = 100
neurons = 100

tf.reset_default_graph()

X = tf.placeholder(tf.float32, [None, time_steps, inputs])
y = tf.placeholder(tf.float32, [None, outputs])

cell = tf.contrib.rnn.BasicLSTMCell(num_units=neurons, activation=tf.nn.relu)
cell_outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)

stacked_outputs = tf.reshape(cell_outputs, [-1, neurons])
out = tf.layers.dense(inputs=stacked_outputs, units=outputs)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(
            labels=y, logits=out))

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(loss)

accuracy = tf.metrics.accuracy(labels =  tf.argmax(y, 1),
                                  predictions = tf.argmax(out, 1),
                                                            name = "accuracy")
precision = tf.metrics.precision(labels=tf.argmax(y, 1),
                                         predictions=tf.argmax(out, 1),
                                                                          name="precision")
recall = tf.metrics.recall(labels=tf.argmax(y, 1),
                                   predictions=tf.argmax(out, 1),
                                                              name="recall")
f1 = 2 * accuracy[1] * recall[1] / ( precision[1] + recall[1] )

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    tf.local_variables_initializer().run()

    for steps in range(epochs):
        mini_batch = zip(range(0, length, batch_size),
                   range(batch_size, length+1, batch_size))

        for (start, end) in mini_batch:
            sess.run(training_op, feed_dict = {X: train_X[start:end,:,:],
                                               y: train_y[start:end,:]})

        if (steps+1) % display == 0:
            loss_fn = loss.eval(feed_dict = {X: train_X, y: train_y})
            print('Step: {}  \tTraining loss: {}'.format((steps+1), loss_fn))

    acc, prec, recall, f1 = sess.run([accuracy, precision, recall, f1],
                                     feed_dict = {X: train_X, y: train_y})

    print('\nEvaluation  on training set')
    print('Accuracy:', acc[1])
    print('Precision:', prec[1])
    print('Recall:', recall[1])
    print('F1 score:', f1)
0
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

У вас есть классификационная сеть: она принимает входные данные или функции (Температура, Масса и Размер) и классифицирует их по одному из ваших классов: 0, 1 или 2. (поле Свойство)

Когда вы изменили исходный набор данных, вы изменили количество классов: с 3 (0,1,2) вы перешли к 1. (1).

Чтобы код работал, вам просто нужно изменить раздел parameters вашего кода, чтобы он соответствовал вашему набору данных.

# parameters
time_steps = 1
inputs = 3
outputs = 1

Примечание: В этом случае я считаю термин outputs немного расплывчатым. Я бы использовал что-то вроде nb_classes

Спасибо. Я изменил название, как было предложено, и попытался запустить пример со следующим изменением данных paste.ubuntu.com/p/NM4bJGnB2b. Я все еще получаю тот же тип ошибки. Вы случайно не понимаете, почему?

Jernej 10.08.2018 15:59

У меня нет проблем с запуском вашего нового примера. Вы уверены, что больше ничего не меняли?

Lescurel 10.08.2018 16:06

Я так не думаю. Вот полный рабочий пример, который все еще использует старое именование paste.ubuntu.com/p/tmXgQfm8GB

Jernej 10.08.2018 16:10

Опять же, без проблем запустить его.

Lescurel 10.08.2018 16:16

Спасибо за попытку. Это странно. Здесь я получаю следующий результат paste.ubuntu.com/p/5YhJ84cPDq при запуске вставленного кода сверху.

Jernej 10.08.2018 16:22
Ответ принят как подходящий

Как правильно указал @Lescurel, в настройке классификации переменная output должна отражать количество классов в целевой переменной.

В то время как в настройке регрессии он будет отражать количество столбцов целевых переменных (при условии, что мы прогнозируем более одной переменной).

Итак, учитывая пример входных данных:

df = pd.DataFrame({'Temperature': [1,2,3,4,5],
                   'Weight': [2,4,6,8,10],
                   'Size': [9,24,9,9,9],
                   'Property': [0,0,0,0,1]})

Количество целевых классов - 2. Отсюда output = 2.

Примечание: Ваш опубликованный код в https://paste.ubuntu.com/p/tmXgQfm8GB/ мне подходит.

Только что заметил, что ваша целевая переменная Property является последним столбцом DataFrame.

   Temperature  Weight  Size  Property
0            1       2     9       0.0
1            2       4    24       0.0
2            3       6     9       0.0
3            4       8     9       1.0
4            5      10     9       NaN

Измените свой код следующим образом вместо:

# X_y_split
train_X = df[:, 1:]
train_y = df[:, 0]

измените его на:

# X_y_split
train_X = df[:, :-1]
train_y = df[:, -1]

Спасибо, что решили это! По какой причине это сработало для вас и Лескуреля, но не для меня? Просто внутреннее упорядочение структуры данных?

Jernej 10.08.2018 17:18

Точно. Внутреннее упорядочение структуры данных имело место. :)

Ekaba Bisong 10.08.2018 17:49

Другие вопросы по теме