博主在使用tensorflow进行深度学习编程的时候经常会遇到一些常见的问题,特此在这里将自己遇到的问题与解决方法进行汇总。
1、tensor张量维度扩展(试图把shape为[64,10]的张量扩展为[64,128,10]的张量)
n = tf.expand_dims(m,axis=1) #m为shape为[64,10]的tensor
#经过tf.expand_dims扩展后的shape为[64,1,10],axis控制增加哪一维度
mn = tf.tile(n,[1,128,1]) #128表示在第二维复制的次数,可以在不同的维度上根据自己的需要进行复制
#经过tf.tile扩展后的shape为[64,128,10]
2、使用梯度裁剪时,由于存在梯度不存在为None,如果使用tf.clip_by_value()时会出现错误:ValueError: None values not supported。
在这里的处理技巧是对梯度不存在为None时不做任何处理,即可避免这个问题。感谢https://stackoverrun.com/cn/q/10826383提供的解决方法,很受用。
opt_func = tf.train.AdamOptimizer(learning_rate=self.config.lr)
gvs = opt_func.compute_gradients(self.loss)
def ClipIfNotNone(grad):
if grad is not None:
return tf.clip_by_value(grad, -10, 10)
capped_gvs = [(ClipIfNotNone(grad), var) for grad, var in gvs]
self.optimizer = opt_func.apply_gradients(grads_and_vars=capped_gvs, global_step=self.global_step)
3、笔者在使用双向RNN中,出现这个错误。InvalidArgumentError: seq_lens() > input.dims()[[Node: hidden/bidirectional_rnn/bw/ReverseSequence。
是因为在对seq进行反转时,序列的长度要超过输入的长度。比如经过padding以后,输入的tensor为[64,100,300],然而你的未经padding的文本实际长度为120,这就导致在发展的时候出现此错误。我们可以考虑将tf.nn.bidirectional_dynamic_rnn()中的sequence_length中的最大值设置为100,就可以避免此问题。在这里特别感谢https://blog.csdn.net/weixin_40015791/article/details/88641806博文对我的帮助。
4、笔者最近在学习Pytorch时,遇到很多坑。比如报错之一的RuntimeError: Invalid device, must be cuda device,笔者在执行print(tensor1.cuda(tensor2.device))时报的错。
是因为在定义张量的时候,没有设置torch.Tensor
分配到的设备的对象。解决方法如下:
import torch
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
#在定义tensor时候添加device值即可
attn=torch.tensor([[1.0,0.0,2.0,3.0],[3.0,3.0,3.0,3.0]],device = device)
a = torch.tensor([[[1],[2],[3],[4]],[[5],[6],[7],[8]]], device=device).float()
b = torch.tensor([[[1,2,3,4]],[[5,6,7,8]]], device=device).float()
c = torch.matmul(a,b)
c = c.eq(0)
print(c)
print(c.cuda(b.device))
5、笔者在Pycharm执行文件时可以执行,在cmd命令行执行时报错:ModuleNotFoundError: No module named 'xxx'。
原因是在命令行运行时,只是搜索当前路径,是找不到你需要导入的model的。解决方法就是在执行文件的开头添加如下代码
import sys
import os
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
注意:根据自己文件目录格式上述代码可能有些不同。
6、如何将CSV文件与json格式文件,参考https://blog.csdn.net/huanbia/article/details/72674832
#group为读取的CSV文件后的数据,我们将其记为df,那么df.to_json(orient='records')后得到的是字符串
#格式如下'[{"columns1":"a","columns2":"b"},{"columns1":"c","columns2":"d"}...]'
string = group.to_json(orient='records')
#接着再使用json.loads将字符串转化为json格式,此时得到的是一个列表
string_list = json.loads(string)
得到的格式如下:[{"columns1":"a","columns2":"b"},{"columns1":"c","columns2":"d"}...]
7、在做NLP有关序列生成模型
笔者参考了seq2seq以及最近较为火爆的transformer模型,在encoder时一般会在setence的后端添加一个停止的符号一般有等,而不需要在文本结尾的时候添加结束符号,后续在自己进行项目任务时需要注意这一点。
8.如何将列表(List)数据转化为数据框(Dataframe)格式?参考链接
第一种是将两个不同的列表转化为数据框
from pandas.core.frame import DataFrame
a=[1,2,3,4]#列表a
b=[5,6,7,8]#列表b
c={"a" : a,
"b" : b}#将列表a,b转换成字典
data=DataFrame(c)#将字典转换成为数据框
print(data)
#结果
a b
0 1 5
1 2 6
2 3 7
3 4 8
第二种是将包含不同子列表的列表转换为数据框
from pandas.core.frame import DataFrame
a=[[1,2,3,4],[5,6,7,8]]#包含两个不同的子列表[1,2,3,4]和[5,6,7,8]
data=DataFrame(a)#这时候是以行为标准写入的
data=data.T#转置之后得到想要的结果
data.rename(columns={0:'a',1:'b'},inplace=True)#注意这里0和1都不是字符串
print(data)
#结果
a b
0 1 5
1 2 6
2 3 7
3 4 8
9.json文件和字符串文件的相互转化,参考
"""json格式转为字符串"""
import json
data = [{
'name' : 'ACME',
'shares' : 100,
'price' : 542.23
}]
json_str = json.dumps(data)
print(json_str)
# 输出
'[{"name": "ACME", "shares": 100, "price": 542.23}]'
"""字符串转化为json格式"""
ans = json.loads(json_str)
print(ans)
#输出
[{'name': 'ACME', 'price': 542.23, 'shares': 100}]
"""注意:读取json文件要用json.load()
保存为json文件时要用json。dump() """
10.npy文件和npz文件保存
楼主在最近做项目时,保存npy和npz文件均正常,但是在load时,npy文件会报错:IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boo......这是引文npy保存文件时数据类型不一致导致,我的解决方法是保存为npz文件,具体格式如下:
np.savez(save_path, arr_name1:np.array1,arr_name2:np.array2.......)
这样再load的时候就不会再报错
11、numpy求点乘距离时可以直接使用numpy中的乘法
常规做法:对于A矩阵,若求A矩阵与其他矩阵们的点乘时,需要A-B做点乘,A-C做点乘,A-D做点乘......
更新做法:对于A矩阵,先复制多份,new_A=[A for i in range(n)],再降B,C,D....汇聚成一起,n为B,C,D.......这些矩阵的数量,然后再直接点乘即可