#python #machine-learning #neural-network
Вопрос:
Я создал простую нейронную сеть, чтобы классифицировать пищу только по двум классам: яйцо или мясо, однако каждый раз, когда я тренирую модель, она дает мне постоянный результат, несмотря на изменение изображения, например, если я тренируюсь в первый раз, она распознает каждое изображение как мясо, а во второй раз она распознает все изображения как яйцо, я не знаю, ошибка ли это в моем коде.
Здесь, где я читаю данные :
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
directory,
labels="inferred",
label_mode="int",
class_names= None,
color_mode="rgb",
batch_size=32,
image_size=(256, 256),
seed=None,
validation_split=None,
subset=None,
interpolation="bilinear",
follow_links=False,
crop_to_aspect_ratio=False
)
Вот где я предсказываю, используя softmax
функцию активации после выравнивания данных :
def forward(x):
return tf.matmul(x,W) b
def model(x):
x = flatten(x)
return activate(x)
def activate(x):
return tf.nn.softmax(forward(x))
вычисление ошибки с использованием cross_entropy
def cross_entropy(y_label, y_pred):
return (-tf.reduce_sum(y_label * tf.math.log(y_pred 1.e-10)))
изменение значений с помощью градиента спуска :
optimizer = tf.keras.optimizers.SGD(learning_rate=0.25)
def train_step(x, y ):
with tf.GradientTape() as tape:
#compute loss function
current_loss = cross_entropy( y, model(x))
# compute gradient of loss
#(This is automatic! Even with specialized funcctions!)
grads = tape.gradient( current_loss , [W,b] )
# Apply SGD step to our Variables W and b
optimizer.apply_gradients( zip( grads , [W,b] ) )
return current_loss.numpy()
и, наконец, обучение модели :
W = tf.Variable(tf.zeros([196608, 2],tf.float32))
# Bias tensor
b = tf.Variable(tf.zeros([2],tf.float32))
loss_values=[]
accuracies = []
epochs = 100
for i in range(epochs):
j=0
# each batch has 50 examples
for x_train_batch, y_train_batch in train_ds:
j =1
current_loss = train_step(x_train_batch/255.0, tf.one_hot(y_train_batch,2))
if jP0 == 0: #reporting intermittent batch statistics
print("epoch ", str(i), "batch", str(j), "loss:", str(current_loss) )
Update:
I have discovered that the problem is in the gradients, they are always zero except for the first time
Комментарии:
1. В функции train_step, где вы выполняете прямой проход через свою сеть и получаете y_pred. y-это аргумент функции, но как вы его вычисляете? Мне кажется, что вы неправильно выполняете прямой пас
2. Я должен отметить, что это не нейронная сеть, которую вы здесь создали, это просто регрессор, так как скрытого слоя нет.
3. кроме того, инициализация ваших W и b до нулей неверна, если только tensorflow не исправляет это на заднем конце, выполнив свою собственную инициализацию, и в этом случае это не проблема, но все равно сбивает с толку.
4. Я не знаю, я все еще учусь, и я следовал учебнику, все, что я изменил, — это набор данных, они используют MNIST, и я использую, как вы видите, мои собственные данные
5. Но я все еще думаю , что это называется нейронной сетью, я думаю, что нейронная сеть-это то, где нейрон попадает на вход с помощью веса, и я действительно хотел инициализировать веса числом вместо нулей, но мои колени замерли
Ответ №1:
Просто для уверенности, действительно ли вы просматриваете данные обучения и используете свой шаг обучения, в предоставленном вами коде нет цикла обучения , который проходит через вас train_ds
, похоже, что ваше поведение больше сводится к инициализации, потому что вы на самом деле не тренируете модель.
Комментарии:
1. Моя ошибка, я неправильно вставил одну и ту же функцию дважды вместо обучающего кода, я обновил вопрос
2. @moumenShobakey Должен попробовать настройку
tf.GradientTape(persistent=True)
в соответствии с документацией tf , она вычисляет градиент только один раз. «Если вы не установите значение persistent=True, градиентная лента может использоваться только для вычисления одного набора градиентов».3. разве на самом деле это не один набор, состоящий из w и b?
4. Эй, я обнаружил, что градиенты действительно равны нулю, за исключением первого раза, поэтому я добавил постоянную и все ту же проблему
Ответ №2:
После нескольких дней отладки я обнаружил, что оценки равны нулю, затем я выяснил, почему, это было связано с тем, что функция softmax, поскольку значения x_train были очень большими, поэтому она выдает нули и единицы, из-за чего изменение стремится к нулю, чтобы обойти, я просто разделил прямые(x) аргументы на большое количество