Почему моя нейронная сеть не может правильно классифицировать?

#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) аргументы на большое количество