トレーニングtensorflow.keras時の損失関数を置き換える方法

フランシス・スケール:

私はトレーニング中に私のニューラルネットワークに関連した損失関数を置き換えたい、これはネットワークです。

model = tensorflow.keras.models.Sequential()
        model.add(tensorflow.keras.layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=input_shape))
        model.add(tensorflow.keras.layers.Conv2D(64, (3, 3), activation="relu"))
        model.add(tensorflow.keras.layers.MaxPooling2D(pool_size=(2, 2)))
        model.add(tensorflow.keras.layers.Dropout(0.25))
        model.add(tensorflow.keras.layers.Flatten())
        model.add(tensorflow.keras.layers.Dense(128, activation="relu"))
        model.add(tensorflow.keras.layers.Dropout(0.5))
        model.add(tensorflow.keras.layers.Dense(output_classes, activation="softmax"))
        model.compile(loss=tensorflow.keras.losses.categorical_crossentropy, optimizer=tensorflow.keras.optimizers.Adam(0.001), metrics=['accuracy'])
        history = model.fit(x_train, y_train, batch_size=128, epochs=5, validation_data=(x_test, y_test))

今私は、変更したいtensorflow.keras.losses.categorical_crossentropy私はこれを作ったので、他に:

model.compile(loss=tensorflow.keras.losses.mse, optimizer=tensorflow.keras.optimizers.Adam(0.001), metrics=['accuracy'])
    history = model.fit(x_improve, y_improve, epochs=1, validation_data=(x_test, y_test)) #FIXME bug during training

しかし、私はこのエラーがあります:

ValueError: No gradients provided for any variable: ['conv2d/kernel:0', 'conv2d/bias:0', 'conv2d_1/kernel:0', 'conv2d_1/bias:0', 'dense/kernel:0', 'dense/bias:0', 'dense_1/kernel:0', 'dense_1/bias:0'].

どうして?どのように私はそれを修正することができますか?損失関数を変更するための別の方法はありますか?

感謝

エドワードGuerriero:

だから、私は与えるだろう簡単な答えは:あなたがゲームのこの種をプレイしたい場合は、スイッチがpytorchします。pytorchにあなたがあなたのトレーニングや評価関数を定義しているので、それは別のものに損失関数からスイッチにちょうどif文を取ります。

また、私は前者が回帰のために後者の分類に適している、あなたはmean_square_errorにcross_entropyから切り替えたいというあなたのコードを見ると、ので、これは本当にあなたが行うことができるものではないが、次のコードでは、私はに平均二乗誤差から切り替え二乗対数平均誤差、両方の回帰に適し損失です。

あなたの質問に他の回答の提供ソリューションにもかかわらず(参照変化する損失機能-動的時のトレーニング)あなたは結果を信頼したりすることはできません天気を、それは明らかではありません。一部の人々は最初の損失であっても、カスタマイズ機能を備えた、時にはKerasのキープ訓練を発見しました。

解決:

私のソリューションは、私たちがforループでモデルを訓練し、それゆえ我々は、新たな損失関数でモデルを再コンパイルすることを好む時はいつでも、それを訓練中止することができますtrain_on_batch、に基づいています。モデルを再コンパイルすることに注意してくださいしない重みをリセットするには、(参照:んが、モデルの重みを再初期化し、再コンパイル?)。

データセットはここで見つけることができボストンハウジングセット

# Regression Example With Boston Dataset: Standardized and Larger
from pandas import read_csv
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import train_test_split
from keras.losses import mean_squared_error, mean_squared_logarithmic_error
from matplotlib import pyplot
import matplotlib.pyplot as plt

# load dataset
dataframe = read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values

# split into input (X) and output (Y) variables
X = dataset[:,0:13]
y = dataset[:,13]

trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.33, random_state=42)

# create model
model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(6, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))

batch_size = 25

# have to define manually a dict to store all epochs scores 
history = {}
history['history'] = {}
history['history']['loss'] = []
history['history']['mean_squared_error'] = []
history['history']['mean_squared_logarithmic_error'] = []
history['history']['val_loss'] = []
history['history']['val_mean_squared_error'] = []
history['history']['val_mean_squared_logarithmic_error'] = []

# first compiling with mse
model.compile(loss='mean_squared_error', optimizer='adam', metrics=[mean_squared_error, mean_squared_logarithmic_error])

# define number of iterations in training and test
train_iter = round(trainX.shape[0]/batch_size)
test_iter = round(testX.shape[0]/batch_size)

for epoch in range(2):

    # train iterations 
    loss, mse, msle = 0, 0, 0
    for i in range(train_iter):

        start = i*batch_size
        end = i*batch_size + batch_size
        batchX = trainX[start:end,]
        batchy = trainy[start:end,]

        loss_, mse_, msle_ = model.train_on_batch(batchX,batchy)

        loss += loss_
        mse += mse_
        msle += msle_

    history['history']['loss'].append(loss/train_iter)
    history['history']['mean_squared_error'].append(mse/train_iter)
    history['history']['mean_squared_logarithmic_error'].append(msle/train_iter)

    # test iterations 
    val_loss, val_mse, val_msle = 0, 0, 0
    for i in range(test_iter):

        start = i*batch_size
        end = i*batch_size + batch_size
        batchX = testX[start:end,]
        batchy = testy[start:end,]

        val_loss_, val_mse_, val_msle_ = model.test_on_batch(batchX,batchy)

        val_loss += val_loss_
        val_mse += val_mse_
        val_msle += msle_

    history['history']['val_loss'].append(val_loss/test_iter)
    history['history']['val_mean_squared_error'].append(val_mse/test_iter)
    history['history']['val_mean_squared_logarithmic_error'].append(val_msle/test_iter)

# recompiling the model with new loss
model.compile(loss='mean_squared_logarithmic_error', optimizer='adam', metrics=[mean_squared_error, mean_squared_logarithmic_error])

for epoch in range(2):

    # train iterations 
    loss, mse, msle = 0, 0, 0
    for i in range(train_iter):

        start = i*batch_size
        end = i*batch_size + batch_size
        batchX = trainX[start:end,]
        batchy = trainy[start:end,]

        loss_, mse_, msle_ = model.train_on_batch(batchX,batchy)

        loss += loss_
        mse += mse_
        msle += msle_

    history['history']['loss'].append(loss/train_iter)
    history['history']['mean_squared_error'].append(mse/train_iter)
    history['history']['mean_squared_logarithmic_error'].append(msle/train_iter)

    # test iterations 
    val_loss, val_mse, val_msle = 0, 0, 0
    for i in range(test_iter):

        start = i*batch_size
        end = i*batch_size + batch_size
        batchX = testX[start:end,]
        batchy = testy[start:end,]

        val_loss_, val_mse_, val_msle_ = model.test_on_batch(batchX,batchy)

        val_loss += val_loss_
        val_mse += val_mse_
        val_msle += msle_

    history['history']['val_loss'].append(val_loss/test_iter)
    history['history']['val_mean_squared_error'].append(val_mse/test_iter)
    history['history']['val_mean_squared_logarithmic_error'].append(val_msle/test_iter)

# Some plots to check what is going on   
# loss function 
pyplot.subplot(311)
pyplot.title('Loss')
pyplot.plot(history['history']['loss'], label='train')
pyplot.plot(history['history']['val_loss'], label='test')
pyplot.legend()

# Only mean squared error 
pyplot.subplot(312)
pyplot.title('Mean Squared Error')
pyplot.plot(history['history']['mean_squared_error'], label='train')
pyplot.plot(history['history']['val_mean_squared_error'], label='test')
pyplot.legend()

# Only mean squared logarithmic error 
pyplot.subplot(313)
pyplot.title('Mean Squared Logarithmic Error')
pyplot.plot(history['history']['mean_squared_logarithmic_error'], label='train')
pyplot.plot(history['history']['val_mean_squared_logarithmic_error'], label='test')
pyplot.legend()
plt.tight_layout()
pyplot.show()

損失関数は、第エポックの後に変更されていること、得られたプロット確認:

ここでは、画像の説明を入力します。

損失関数の低下は、モデルがはるかに低い値を有する対数いずれかに正常平均二乗誤差からスイッチングされるという事実によるものです。スコアの印刷も使用損失が本当に変更されたことを証明します:

print(history['history']['loss'])
[599.5209197998047, 570.4041115897043, 3.8622902120862688, 2.1578191178185597]
print(history['history']['mean_squared_error'])
[599.5209197998047, 570.4041115897043, 510.29034205845426, 425.32058388846264]
print(history['history']['mean_squared_logarithmic_error'])
[8.624503476279122, 6.346359729766846, 3.8622902120862688, 2.1578191178185597]

値損失の値はmean_square_errorのものに等しい最初の二つのエポックに第3および第4のエポック中に設定された新たな損失であり、mean_square_logarithmic_errorのものと等しくなります。train_on_batchを使用して、私は、これは1がpytorchの行動は、(このシナリオでは、私の違いで、同じ結果を達成するためにpytochに何をすべきか、基本的であることを再度強調したいそれにもかかわらず、変更損失関数にできることと思われるので、意見が)、より信頼性があります。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=408718&siteId=1