在pytorch中动态调整优化器的学习率方式
在深度学习中,经常需要动态调整学习率,以达到更好地训练效果,本文纪录在pytorch中的实现方法,其优化器实例为SGD优化器,其他如Adam优化器同样适用。
一般来说,在以SGD优化器作为基本优化器,然后根据epoch实现学习率指数下降,代码如下:
step=[10,20,30,40] base_lr=1e-4 sgd_opt=torch.optim.SGD(model.parameters(),lr=base_lr,nesterov=True,momentum=0.9) defadjust_lr(epoch): lr=base_lr*(0.1**np.sum(epoch>=np.array(step))) forparams_groupinsgd_opt.param_groups: params_group['lr']=lr returnlr
只需要在每个train的epoch之前使用这个函数即可。
forepochinrange(60): model.train() adjust_lr(epoch) forind,eachinenumerate(train_loader): mat,label=each ...
补充知识:Pytorch框架下应用Bi-LSTM实现汽车评论文本关键词抽取
需要调用的模块及整体Bi-lstm流程
importtorch importpandasaspd importnumpyasnp fromtensorflowimportkeras importtorch.nnasnn importtorch.nn.functionalasF importtorch.optimasoptim fromtorch.utils.dataimportDataLoader fromtorch.utils.dataimportTensorDataset importgensim fromsklearn.model_selectionimporttrain_test_split classword_extract(nn.Module): def__init__(self,d_model,embedding_matrix): super(word_extract,self).__init__() self.d_model=d_model self.embedding=nn.Embedding(num_embeddings=len(embedding_matrix),embedding_dim=200) self.embedding.weight.data.copy_(embedding_matrix) self.embedding.weight.requires_grad=False self.lstm1=nn.LSTM(input_size=200,hidden_size=50,bidirectional=True) self.lstm2=nn.LSTM(input_size=2*self.lstm1.hidden_size,hidden_size=50,bidirectional=True) self.linear=nn.Linear(2*self.lstm2.hidden_size,4) defforward(self,x): w_x=self.embedding(x) first_x,(first_h_x,first_c_x)=self.lstm1(w_x) second_x,(second_h_x,second_c_x)=self.lstm2(first_x) output_x=self.linear(second_x) returnoutput_x
将文本转换为数值形式
deftrans_num(word2idx,text):
text_list=[]
foriintext:
s=i.rstrip().replace('\r','').replace('\n','').split('')
numtext=[word2idx[j]ifjinword2idx.keys()elseword2idx['_PAD']forjins]
text_list.append(numtext)
returntext_list
将Gensim里的词向量模型转为矩阵形式,后续导入到LSTM模型中
defestablish_word2vec_matrix(model):#负责将数值索引转为要输入的数据
word2idx={"_PAD":0}#初始化`[word:token]`字典,后期tokenize语料库就是用该词典。
num2idx={0:"_PAD"}
vocab_list=[(k,model.wv[k])fork,vinmodel.wv.vocab.items()]
#存储所有word2vec中所有向量的数组,留意其中多一位,词向量全为0,用于padding
embeddings_matrix=np.zeros((len(model.wv.vocab.items())+1,model.vector_size))
foriinrange(len(vocab_list)):
word=vocab_list[i][0]
word2idx[word]=i+1
num2idx[i+1]=word
embeddings_matrix[i+1]=vocab_list[i][1]
embeddings_matrix=torch.Tensor(embeddings_matrix)
returnembeddings_matrix,word2idx,num2idx
训练过程
deftrain(model,epoch,learning_rate,batch_size,x,y,val_x,val_y):
optimizor=optim.Adam(model.parameters(),lr=learning_rate)
data=TensorDataset(x,y)
data=DataLoader(data,batch_size=batch_size)
foriinrange(epoch):
forj,(per_x,per_y)inenumerate(data):
output_y=model(per_x)
loss=F.cross_entropy(output_y.view(-1,output_y.size(2)),per_y.view(-1))
optimizor.zero_grad()
loss.backward()
optimizor.step()
arg_y=output_y.argmax(dim=2)
fit_correct=(arg_y==per_y).sum()
fit_acc=fit_correct.item()/(per_y.size(0)*per_y.size(1))
print('##################################')
print('第{}次迭代第{}批次的训练误差为{}'.format(i+1,j+1,loss),end='')
print('第{}次迭代第{}批次的训练准确度为{}'.format(i+1,j+1,fit_acc))
val_output_y=model(val_x)
val_loss=F.cross_entropy(val_output_y.view(-1,val_output_y.size(2)),val_y.view(-1))
arg_val_y=val_output_y.argmax(dim=2)
val_correct=(arg_val_y==val_y).sum()
val_acc=val_correct.item()/(val_y.size(0)*val_y.size(1))
print('第{}次迭代第{}批次的预测误差为{}'.format(i+1,j+1,val_loss),end='')
print('第{}次迭代第{}批次的预测准确度为{}'.format(i+1,j+1,val_acc))
torch.save(model,'./extract_model.pkl')#保存模型
主函数部分
if__name__=='__main__':
#生成词向量矩阵
word2vec=gensim.models.Word2Vec.load('./word2vec_model')
embedding_matrix,word2idx,num2idx=establish_word2vec_matrix(word2vec)#输入的是词向量模型
#
train_data=pd.read_csv('./数据.csv')
x=list(train_data['文本'])
#将文本从文字转化为数值,这部分trans_num函数你需要自己改动去适应你自己的数据集
x=trans_num(word2idx,x)
#x需要先进行填充,也就是每个句子都是一样长度,不够长度的以0来填充,填充词单独分为一类
##也就是说输入的x是固定长度的数值列表,例如[50,123,1850,21,199,0,0,...]
#输入的y是[2,0,1,0,0,1,3,3,3,3,3,.....]
#填充代码你自行编写,以下部分是针对我的数据集
x=keras.preprocessing.sequence.pad_sequences(
x,maxlen=60,value=0,padding='post',
)
y=list(train_data['BIO数值'])
y_text=[]
foriiny:
s=i.rstrip().split('')
numtext=[int(j)forjins]
y_text.append(numtext)
y=y_text
y=keras.preprocessing.sequence.pad_sequences(
y,maxlen=60,value=3,padding='post',
)
#将数据进行划分
fit_x,val_x,fit_y,val_y=train_test_split(x,y,train_size=0.8,test_size=0.2)
fit_x=torch.LongTensor(fit_x)
fit_y=torch.LongTensor(fit_y)
val_x=torch.LongTensor(val_x)
val_y=torch.LongTensor(val_y)
#开始应用
w_extract=word_extract(d_model=200,embedding_matrix=embedding_matrix)
train(model=w_extract,epoch=5,learning_rate=0.001,batch_size=50,
x=fit_x,y=fit_y,val_x=val_x,val_y=val_y)#可以自行改动参数,设置学习率,批次,和迭代次数
w_extract=torch.load('./extract_model.pkl')#加载保存好的模型
pred_val_y=w_extract(val_x).argmax(dim=2)
以上这篇在pytorch中动态调整优化器的学习率方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。