Keras:在一个新实验中重用训练有素的砝码

时间:2019-02-03 15:01:10

标签: python tensorflow machine-learning keras neural-network

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

如果要在不同的数据集上训练新模型(例如model_2),那么将从权重的初始随机分布中获得基线。

我想知道,那么是否有可能训练model_1和model_2,而这是我不知道该怎么做的地方。我可以从model_1(具有经过训练的权重)中提取两个256和128的密集层,并将它们用作model_3的起点-这是具有model_1初始权重分布的数据集2?

最后,我有以下内容:

  1. 模型_1 ,该模型从随机分布开始,并在数据集1
  2. 上进行训练
  3. Model_2 ,它从随机分布开始,并在数据集2
  4. 上进行训练
  5. 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:两个数据集之间的输入属性和输出将完全相同,所有更改的都是属性值。我很好奇,如果两个数据集具有不同数量的输出类别,可以这样做吗?

1 个答案:

答案 0 :(得分:0)

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

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

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