python - Keras:在新实验中重用训练过的权重
问题描述
我对 Keras 很陌生,所以提前为任何愚蠢的错误道歉。我目前正在尝试在两个数据集之间尝试一些好的旧跨域迁移学习。我在这里有一个模型,它在我生成的语音识别数据集上训练和执行(代码在这个问题的底部,因为它很长)
如果我要训练一个新模型,比如在不同的数据集上使用 model_2,那么我会从权重的初始随机分布中获得基线。
我想知道,是否可以训练model_1和model_2,这是我不知道该怎么做的一点;我可以从model_1(具有训练的权重)中获取两个256和128密集层并将它们用作model_3的起点 - 这是具有来自model_1的初始权重分布的数据集2?
所以,最后,我有以下几点:
- Model_1从随机分布开始并在数据集 1上进行训练
- Model_2从随机分布开始并在数据集 2上进行训练
- 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:两个数据集之间的输入属性和输出都将相同,所有会改变的是属性值。我很好奇,如果两个数据集具有不同数量的输出类,可以这样做吗?
解决方案
简而言之,要从 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'))
推荐阅读
- python - 如何修复 SQLAlchemy 连接问题:连接到 IBM Cloud 上托管的 IBM db2 服务器时出现“需要 SQLAlchemy 格式的连接信息”
- shader - 在 HLSL 片段着色器中实例化
- http - http可以在其他平台上使用吗?
- shell - 在后台使用 find gun 执行 shell
- apache-spark - Spark vs Hadoop 这个简单的例子?
- arrays - 在 React Native 中显示嵌套对象数组中的所有数据
- c - 如何使用正确提供的 argc、argv、envp 从 NASM 调用用 C 编写的链接可执行文件中的主函数
- apache-spark - 由于节点故障和源数据更改,从初始源一直重新计算 Spark 分区
- scala - 数组列中的Scala DataFrame过滤器值
- c++ - 为什么这是一个常量字符,而不是正常字符?