Я обучил логистическую регрессию с помощью tf.GradientTape, но она не может сходиться
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
xs = np.array([[1, 1], [-1, -1], [-1, -1.1]])
ys = np.array([1, 0, 0])
def lr_model():
inputs = keras.Input(shape=(2))
outputs = layers.Dense(1, activation='sigmoid')(inputs)
return keras.Model(inputs=inputs, outputs=outputs)
model = lr_model()
model.compile(loss=keras.losses.BinaryCrossentropy(),
optimizer=keras.optimizers.SGD(0.1),
metrics=['accuracy'])
history = model.fit(xs, ys, batch_size=3, epochs=10)
for i in range(10):
print(i, history.history['loss'][i], history.history['accuracy'][i])
сходится и результаты:
0 1,04525887966156 0,0
1 0,9557339549064636 0,0
2 0,8753216862678528 0,0
3 0,8033372759819031 0,0
4 0,7390384674072266 0,0
5 0,6816689968109131 0,6666667
6 0,6304909586906433 1,0
7 0,5848075151443481 1,0
8 0,5439766049385071 1,0
9 0.5074175596237183 1,0
Но я хочу написать свой тренировочный процесс, указанный ниже:
train_loss = keras.metrics.Mean(name='train_loss')
train_acc = keras.metrics.BinaryAccuracy()
model = lr_model()
optimizer = keras.optimizers.SGD(0.1)
def train_step(data, labels):
with tf.GradientTape() as tape:
data = tf.cast(data, tf.float32)
pred = model(data)
loss = keras.losses.binary_crossentropy(labels, pred)
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
train_loss(loss)
train_acc(labels, pred)
for i in range(100):
train_loss.reset_states()
train_acc.reset_states()
train_step(xs, ys)
if i % 10 == 0:
print(i, train_loss.result().numpy(),train_acc.result().numpy())
Это не может сходиться, как в предыдущем примере, и я не знаю, почему
0 0,7586897 1,0
10 0,6607897 1,0
20 0,64341 0,6666667
30 0,63867164 0,6666667
40 0,63722247 0,6666667
50 0,63676286 0,6666667
60 0,63661444 0,6666667
70 0,636566 0,6666667
80 0,63654995 0,6666667
90 0,6365447 0,6666667
В чем проблема с моими кодами? И как мне изменить мои обучающие коды с помощью tf.GradientTape, чтобы они сходились, как это делает компиляция / подгонка keras? Спасибо