每次训练模型时,都会收到不同的结果-为什么?

时间:2020-04-16 03:17:52

标签: tensorflow tensorflow2.0

  • 我不明白我做错了什么-每次启动此代码时,我都会收到different result
  • 我发现更改批次大小时结果会有所不同,但准确性不应取决于批次大小。
  • 图表看上去完全不符合我的预期

有人可以指出我的错误吗?

%reload_ext autoreload
%autoreload 2
%matplotlib inline

## Load dataset
import tensorflow as tf
tf.config.set_soft_device_placement(True)
tf.debugging.set_log_device_placement(True)

import tensorflow_datasets as tfds # must be 2.1
import matplotlib.pyplot as plt


builder = tfds.builder('beans')
info = builder.info
builder.download_and_prepare()
datasets = builder.as_dataset()
raw_train_dataset, raw_test_dataset = datasets['train'], datasets['test']

## Build a model
def get_model(image_width:int, image_height:int, num_classes:int):
    model = tf.keras.Sequential()
    #layer 1 
    model.add(tf.keras.layers.Conv2D(filters=96, kernel_size=(11,11), strides= 4, padding= 'valid',
        activation=tf.keras.activations.relu, input_shape=(image_width, image_height ,3)))
    model.add(tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2,2),padding= 'valid'))
    # layer 2
    model.add(tf.keras.layers.Conv2D(filters=256, kernel_size=(5,5), strides= 1, padding='same', 
        activation=tf.keras.activations.relu))
    model.add(tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2,2), padding= 'valid'))
    # layer 3
    model.add(tf.keras.layers.Conv2D(filters=384, kernel_size=(3,3), strides= 1, padding= 'same', activation=tf.keras.activations.relu))
    model.add(tf.keras.layers.Conv2D(filters=384, kernel_size=(3,3), strides= 1, padding= 'same', activation=tf.keras.activations.relu))
    model.add(tf.keras.layers.Conv2D(filters=256, kernel_size=(3,3), strides= 1, padding= 'same', activation=tf.keras.activations.relu))
    model.add(tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2,2), padding= 'valid'))

    # layer4 4
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(4096, activation=tf.keras.activations.relu))
    model.add(tf.keras.layers.Dropout(0.5))
    # layer4 4
    model.add(tf.keras.layers.Dense(4096, activation=tf.keras.activations.relu))
    model.add(tf.keras.layers.Dropout(0.5))
    # layer4 5
    model.add(tf.keras.layers.Dense(1000, activation = 'relu'))
    model.add(tf.keras.layers.Dropout(0.5))
    # layer4 6
    model.add(tf.keras.layers.Dense(num_classes, activation = 'softmax'))

    return model

IMAGE_width = 500
IMAGE_height = 500
NUM_CLASSES = info.features["label"].num_classes
CLASS_NAMES = info.features["label"].names

model = get_model(IMAGE_width, IMAGE_height, NUM_CLASSES)
result = model.compile( loss=tf.keras.losses.CategoricalCrossentropy(), 
                        optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
                        metrics=['accuracy'])
## Train
def prepare_record(record):
    image = record['image']
    # image = tf.image.resize(image, (image_width,image_height))
    # image = tf.cast(image, tf.int32)
    label = record['label']
    return image, label 

train_dataset = raw_train_dataset.map(prepare_record, num_parallel_calls=tf.data.experimental.AUTOTUNE).shuffle(1034).batch(517).prefetch(tf.data.experimental.AUTOTUNE)

for train_image_batch, train_label_batch in train_dataset:
    train_one_hot_y = tf.one_hot(train_label_batch, NUM_CLASSES    )
    history = model.fit(train_image_batch, train_one_hot_y, epochs=10, verbose=0,validation_split=0.2)

plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'val'], loc='upper left')
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'val'], loc='upper left')
plt.show()

1 个答案:

答案 0 :(得分:0)

fit函数中,有一个名为shuffle的参数:

布尔值(是否在每个纪元之前改组训练数据)或str(用于“批处理”)。 “批处理”是处理HDF5数据限制的特殊选项;它以批量大小的块洗牌。当steps_per_epoch不是None时无效。

如果将其设置为False,则结果应相等。

另一种可能更可取的方法是使用tf.random.set_seed(seed),这样混洗总是以相同的方式执行(请参见docs)。