首页 > 解决方案 > Keras:在新实验中重用训练过的权重

问题描述

我对 Keras 很陌生,所以提前为任何愚蠢的错误道歉。我目前正在尝试在两个数据集之间尝试一些好的旧跨域迁移学习。我在这里有一个模型,它在我生成的语音识别数据集上训练和执行(代码在这个问题的底部,因为它很长)

如果我要训练一个新模型,比如在不同的数据集上使用 model_2,那么我会从权重的初始随机分布中获得基线。

我想知道,是否可以训练model_1和model_2,这是我不知道该怎么做的一点;我可以从model_1(具有训练的权重)中获取两个256和128密集层并将它们用作model_3的起点 - 这是具有来自model_1的初始权重分布的数据集2?

所以,最后,我有以下几点:

  1. Model_1从随机分布开始并在数据集 1上进行训练
  2. Model_2从随机分布开始并在数据集 2上进行训练
  3. Model_3从在 Model_1 中训练的分布开始并在数据集 2上训练。

我的问题是,我将如何进行上面的第 3 步?我不想冻结权重,我只想从过去的实验中得到一个用于训练的初始分布

任何帮助将不胜感激。谢谢!抱歉,如果我没有说清楚我要做什么

我训练 Model_1 的代码如下:

import numpy
import pandas
from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import EarlyStopping
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
import matplotlib.pyplot as plt
from keras.utils import np_utils
from keras.layers.normalization import BatchNormalization

import time
start = time.clock()



# fix random seed for reproducibility
seed = 1
numpy.random.seed(seed)

# load dataset
dataframe = pandas.read_csv("voice.csv", header=None)
dataset = dataframe.values
# split into input (X) and output (Y) variables
numVars = len(dataframe.columns) - 1
numClasses  =  dataframe[numVars].nunique()
X = dataset[:,0:numVars].astype(float)
Y = dataset[:,numVars]


print("THERE ARE " + str(numVars) + " ATTRIBUTES")
print("THERE ARE " + str(numClasses) + " UNIQUE CLASSES")




# encode class values as integers
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)

# convert integers to dummy variables (i.e. one hot encoded)
dummy_y = np_utils.to_categorical(encoded_Y)


calls = [EarlyStopping(monitor='acc', min_delta=0.0001, patience=100, verbose=2, mode='max', restore_best_weights=True)]

# define baseline model
def baseline_model():
    # create model

    model = Sequential()

    model.add(BatchNormalization())

    model.add(Dense(256, input_dim=numVars, activation='sigmoid'))

    model.add(Dense(128, activation='sigmoid'))

    model.add(Dense(numClasses, activation='softmax'))
    # Compile model
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model


estimator = KerasClassifier(build_fn=baseline_model, epochs=2000, batch_size=1000, verbose=1)
kfold = KFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(estimator, X, dummy_y, cv=kfold, fit_params={'callbacks':calls})
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
#your code here    
print (time.clock() - start)

PS:两个数据集之间的输入属性和输出都将相同,所有会改变的是属性值。我很好奇,如果两个数据集具有不同数量的输出类,可以这样做吗?

标签: pythontensorflowmachine-learningkerasneural-network

解决方案


简而言之,要从 Model_1 微调 Model_3,只需调用model.load_weights('/path/to/model_1.h5', by_name=True)after model.compile(...)。当然,你必须先保存训练好的 Model_1。

如果我理解正确,您在两个数据集中具有相同数量的特征和类,因此您甚至不需要重新设计您的模型。如果您有不同的类集,那么您必须为 Model_1 和 Model_3 的最后一层赋予不同的名称:

model.add(Dense(numClasses, activation='softmax', name='some_unique_name'))

推荐阅读