Python Keras.fit的性能优于手动Tensorflow
我不熟悉Tensorflow和Keras。为了开始,我遵循了教程。我现在正在调整它,以在CIFAR10而不是MNIST数据集上进行训练。我重新创建了这个模型,并尝试在自己的代码库中运行它 从逻辑上讲,如果模型、批量大小和优化器都是相同的,那么它们的执行应该是相同的,但它们不是。我想可能是我在准备数据时犯了一个错误。因此,我将model.fit函数从keras代码复制到脚本中,它的性能仍然更好。使用.fit可以在25个时间段内为我提供大约75%的准确度,而使用手动方法则需要大约60个时间段。使用.fit,我还可以获得稍好的最大精确度 我想知道的是:是否适合在幕后做一些优化训练的事情?我需要向代码中添加什么才能获得相同的性能?我是不是做错了什么 谢谢你抽出时间 主要代码:Python Keras.fit的性能优于手动Tensorflow,python,tensorflow,keras,deep-learning,Python,Tensorflow,Keras,Deep Learning,我不熟悉Tensorflow和Keras。为了开始,我遵循了教程。我现在正在调整它,以在CIFAR10而不是MNIST数据集上进行训练。我重新创建了这个模型,并尝试在自己的代码库中运行它 从逻辑上讲,如果模型、批量大小和优化器都是相同的,那么它们的执行应该是相同的,但它们不是。我想可能是我在准备数据时犯了一个错误。因此,我将model.fit函数从keras代码复制到脚本中,它的性能仍然更好。使用.fit可以在25个时间段内为我提供大约75%的准确度,而使用手动方法则需要大约60个时间段。使用.
import tensorflow as tf
from tensorflow import keras
import msvcrt
from Plotter import Plotter
#########################Configuration Settings#############################
BatchSize = 32
ModelName = "CifarModel"
############################################################################
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
print("x_train",x_train.shape)
print("y_train",y_train.shape)
print("x_test",x_test.shape)
print("y_test",y_test.shape)
x_train, x_test = x_train / 255.0, x_test / 255.0
# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)
train_ds = tf.data.Dataset.from_tensor_slices(
(x_train, y_train)).batch(BatchSize)
test_ds = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(BatchSize)
loss_object = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.0001,decay=1e-6)
# Create an instance of the model
model = ModelManager.loadModel(ModelName,10)
train_loss = tf.keras.metrics.Mean(name='train_loss')
train_accuracy = tf.keras.metrics.CategoricalAccuracy(name='train_accuracy')
test_loss = tf.keras.metrics.Mean(name='test_loss')
test_accuracy = tf.keras.metrics.CategoricalAccuracy(name='test_accuracy')
########### Using this function I achieve better results ##################
model.compile(loss='categorical_crossentropy',
optimizer=optimizer,
metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=BatchSize,
epochs=100,
validation_data=(x_test, y_test),
shuffle=True,
verbose=2)
############################################################################
########### Using the below code I achieve worse results ##################
@tf.function
def train_step(images, labels):
with tf.GradientTape() as tape:
predictions = model(images, training=True)
loss = loss_object(labels, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
train_loss(loss)
train_accuracy(labels, predictions)
@tf.function
def test_step(images, labels):
predictions = model(images, training=False)
t_loss = loss_object(labels, predictions)
test_loss(t_loss)
test_accuracy(labels, predictions)
epoch = 0
InterruptLoop = False
while InterruptLoop == False:
#Shuffle training data
train_ds.shuffle(1000)
epoch = epoch + 1
# Reset the metrics at the start of the next epoch
train_loss.reset_states()
train_accuracy.reset_states()
test_loss.reset_states()
test_accuracy.reset_states()
for images, labels in train_ds:
train_step(images, labels)
for test_images, test_labels in test_ds:
test_step(test_images, test_labels)
test_accuracy = test_accuracy.result() * 100
train_accuracy = train_accuracy.result() * 100
#Print update to console
template = 'Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, Test Accuracy: {}'
print(template.format(epoch,
train_loss.result(),
train_accuracy ,
test_loss.result(),
test_accuracy))
# Check if keyboard pressed
while msvcrt.kbhit():
char = str(msvcrt.getch())
if char == "b'q'":
InterruptLoop = True
print("Stopping loop")
模型:
from tensorflow.keras.layers import Dense, Flatten, Conv2D, Dropout, MaxPool2D
from tensorflow.keras import Model
class ModelData(Model):
def __init__(self,NumberOfOutputs):
super(ModelData, self).__init__()
self.conv1 = Conv2D(32, 3, activation='relu', padding='same', input_shape=(32,32,3))
self.conv2 = Conv2D(32, 3, activation='relu')
self.maxpooling1 = MaxPool2D(pool_size=(2,2))
self.dropout1 = Dropout(0.25)
############################
self.conv3 = Conv2D(64,3,activation='relu',padding='same')
self.conv4 = Conv2D(64,3,activation='relu')
self.maxpooling2 = MaxPool2D(pool_size=(2,2))
self.dropout2 = Dropout(0.25)
############################
self.flatten = Flatten()
self.d1 = Dense(512, activation='relu')
self.dropout3 = Dropout(0.5)
self.d2 = Dense(NumberOfOutputs,activation='softmax')
def call(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.maxpooling1(x)
x = self.dropout1(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.maxpooling2(x)
x = self.dropout2(x)
x = self.flatten(x)
x = self.d1(x)
x = self.dropout3(x)
x = self.d2(x)
return x
在这里提及解决方案(答案部分),即使它出现在评论中,也是为了社区的利益 在相同的
数据集
上,使用Keras模型时,准确度可能会有所不同。如果数据被洗牌,主要是因为我们洗牌数据时,训练和测试(或验证)之间的数据分割,则使用Tensorflow构建的模型
拟合
在这两种情况下(Keras和Tensorflow),将产生不同的列车和测试数据
如果我们想在Keras
和Tensorflow
中观察相同数据集和具有类似架构的类似结果,我们可以关闭数据洗牌
希望这有帮助。学习愉快 我没有用过,但我很肯定它和我的不一样。如果是这样的话,那么你就试着用两个不同的指标来比较结果。我不确定keras的fit方法中隐藏了什么,但我认为不同的洗牌会增加差异。您可以尝试使用keras方法对批次进行培训,确保keras和tf的批次相同。最后一件事:两个模型的渐近行为如何?100或200个时代之后会发生什么?在我看来,基准应该在大量的时代之后进行评估,以删除任何内部波动。谢谢你的评论!根据(在“度量”下),字符串“精度”将转换为最合适的度量。我将字符串更改为“CategoricalAccuracy”,以确保得到完全相同的结果。fit仍然表现得更好。我关闭了这两个选项的洗牌功能,但没有什么不同。在批处理中使用train_与“fit”方法的结果相同,尽管其他方法与手动方法相同。渐进:虽然拟合方法在+-60个时期内达到,手动方法仅在130个时期左右达到,但它们稳定在相同的值(该模型预计为78-80%)。它们最终将稳定到几乎相同的值,但使用fit总是在较少的时间内使其更接近。将Adam与手动方法和过多的参数一起使用可能会导致不稳定,但使用相同设置进行拟合永远不会变得不稳定。您是否偶然发现model.fit()与手动方法之间存在差异的原因?我的数据集遇到了类似的问题,我不知道为什么。我还没试过关闭洗牌,但你说它什么都没做,所以我怀疑还有别的东西在起作用。