预训练Bert模型输出类型为str问题解决
1 2 3 4 5 6 7 8 9 10 | input_ids = keras.layers. Input (shape = (MAXLEN,),dtype = 'int32' ) attention_mask = keras.layers. Input (shape = (MAXLEN,),dtype = 'int32' ) token_type_ids = keras.layers. Input (shape = (MAXLEN,),dtype = 'int32' ) _,x = bert_model([input_ids,attention_mask,token_type_ids]) outputs = keras.layers.Dense( 1 ,activation = 'sigmoid' )(x) #给模型加一个全连接层,将bert的输出x调整后用sigmoid函数做一个二分类 model = keras.models.Model(inputs = [input_ids,attention_mask,token_type_ids],outputs = outputs) model. compile (loss = 'binary_crossentropy' ,optimizer = keras.optimizers.Adam(lr = LEARNING_RATE),metrics = [ 'accuracy' ]) |
这是一段用预训练的bert模型来构造一个文本分类器的代码。在代码中,先用设定好的输入,输入模型得到最后一层隐藏层的输出,作为变量x再输入全连接层,再经过sigmiod函数来实现二分类的效果。最后将全连接层加入到模型中,设置好损失函数等参数进行编译。
_,x=bert_model([input_ids,attention_mask,token_type_ids]) 这句的作用是获取bert模型的最后一池化层的输出。
在运行代码时,每次运行到Dense层就会报错提示格式错误,type(x)查看x的格式,发现它的输出是一个名为pooler_output的字符串,这显然不合要求:模型的输出应该是一个张量而不是字符串,而全连接层需要的也是一个二维的张量。但如果使用x=tf.convert_to_tensor(x)强制将x转为张量,那么得到的是一个丢失了形状信息的空张量。
在网上查找资料后发现, 这和tranformers库的版本有关系。在transfromer库3.X版本后,模型不再返回张量的元组,而是返回特定对象。pip show transformer指令查看版本。如果版本高于4.0,那么输出的确实会是字符串,解决办法是在一开始的模型定义语句里增加一个参数return_dict=flase,让模型正确返回一个元组。
如果不想考虑这么麻烦,或者加上了return_dict后,解释器报错,那就直接用
x=bert_model([input_ids,attention_mask,token_type_ids])[1]即可。因为模型的输出是包含两个张量的元组。第一部分是所有时刻的输出,第二部分就是最后一层隐藏层的输出。用[1]就能直接得到最后一层张量,避免了格式问题。不得不说这不是什么大问题,但遇到以后真的很糟心。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)