Hasil berbeda menggunakan pembelajaran mendalam di Keras

Saya melakukan klasifikasi teks menggunakan jaringan saraf dalam dengan keras mengikuti tutorial, tetapi ketika saya menjalankan kode berikut beberapa kali, saya mendapatkan hasil yang berbeda.

Misalnya, kerugian pengujian pada putaran pertama adalah 0,88815, dan pada putaran kedua adalah 0,89030 yang berarti sedikit lebih tinggi. Saya bertanya-tanya dari mana datangnya keacakan itu?

import keras
from keras.datasets import reuters


(x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=None, test_split=0.2)
word_index = reuters.get_word_index(path="reuters_word_index.json")



print('# of Training Samples: {}'.format(len(x_train)))
print('# of Test Samples: {}'.format(len(x_test)))

num_classes = max(y_train) + 1
print('# of Classes: {}'.format(num_classes))

index_to_word = {}
for key, value in word_index.items():
    index_to_word[value] = key

print(' '.join([index_to_word[x] for x in x_train[0]]))
print(y_train[0])


from keras.preprocessing.text import Tokenizer

max_words = 10000

tokenizer = Tokenizer(num_words=max_words)
x_train = tokenizer.sequences_to_matrix(x_train, mode='binary')
x_test = tokenizer.sequences_to_matrix(x_test, mode='binary')

y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)


print(x_train[0])
print(len(x_train[0]))

print(y_train[0])
print(len(y_train[0]))


from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation

model = Sequential()
model.add(Dense(512, input_shape=(max_words,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))



model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.metrics_names)

batch_size = 32
epochs = 3

history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.1)
score = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=1)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

person jinreal2014    schedule 30.08.2018    source sumber


Jawaban (4)


Jika Anda ingin mendapatkan hasil yang sama setiap kali Anda perlu menambahkan benih secara acak. Lihat juga https://machinelearningmastery.com/reproducible-results-neural-networks-keras/.

Ini dapat dilakukan hanya dengan menambahkan:

from numpy.random import seed
seed(42)

Dan jika Anda menggunakan backend Tensorflow, Anda juga perlu menambahkan:

from tensorflow import set_random_seed
set_random_seed(42)

42 hanyalah angka sembarang yang dapat Anda pilih sesuai keinginan Anda. Ini hanyalah sebuah konstanta untuk seed acak sehingga Anda akan selalu mendapatkan inisialisasi acak yang sama untuk bobot Anda. Ini kemudian akan memberi Anda hasil yang sama.

person WurzelseppQX    schedule 30.08.2018

Ini adalah perilaku keras yang biasa. Lihat diskusi ini di daftar masalah repositori keras github.

Misalnya, dalam fungsi fit, argumen ke-9 adalah pengacakan. Secara default, ini disetel ke true. Jadi, di setiap epoch, data akan diacak sebelum dijalankan. Hal ini menyebabkan nilainya berubah setiap waktu.

Menetapkan benih secara acak, akan membantu. Tapi, masih belum sepenuhnya tepat.

person Gimhani    schedule 30.08.2018

Seperti disebutkan dalam FAQ Keras tambahkan kode berikut:

import numpy as np
import tensorflow as tf
import random as rn

# The below is necessary in Python 3.2.3 onwards to
# have reproducible behavior for certain hash-based operations.
# See these references for further details:
# https://docs.python.org/3.4/using/cmdline.html#envvar-PYTHONHASHSEED
# https://github.com/keras-team/keras/issues/2280#issuecomment-306959926

import os
os.environ['PYTHONHASHSEED'] = '0'

# The below is necessary for starting Numpy generated random numbers
# in a well-defined initial state.

np.random.seed(42)

# The below is necessary for starting core Python generated random numbers
# in a well-defined state.

rn.seed(12345)

# Force TensorFlow to use single thread.
# Multiple threads are a potential source of
# non-reproducible results.
# For further details, see: https://stackoverflow.com/questions/42022950/which-seeds have-to-be-set-where-to-realize-100-reproducibility-of-training-res

session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, 
inter_op_parallelism_threads=1)

from keras import backend as K

# The below tf.set_random_seed() will make random number generation
# in the TensorFlow backend have a well-defined initial state.
# For further details, see: https://www.tensorflow.org/api_docs/python/tf/set_random_seed

tf.set_random_seed(1234)

sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)

# Rest of code follows ...
person Vikranth    schedule 30.08.2018

Saya tidak memeriksa dengan GPU, tetapi untuk CPU Tampaknya tidak berfungsi dengan memperbaiki seed seperti di atas dengan Tensorflow 1 sebagai back end Keras. Oleh karena itu, kita perlu mengubah Tensorflow 1 menjadi Tensorflow 2. Kemudian, benih perbaikan akan berfungsi. Misalnya, ini berhasil untuk saya.

import os
import numpy as np
import random as rn
import tensorflow as tf

os.environ['PYTHONHASHSEED']= '0'
np.random.seed(1)
rn.seed(1)
tf.set_random_seed(1)
person Nguyen Trung Ky    schedule 05.04.2021