【深度学习】小技巧小知识备忘录

model.modules()

是对模型的所有不同层面的子层,子层的子层进行输出,组成一个的一个list。
比如:

listm[2]
Out[20]: 
ConvBNActivation(
  (0): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
  (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU6(inplace=True)
)
listm[3]
Out[21]: Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
listm[4]
Out[22]: BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)

第三个元素是第1个元素的子层,第四个元素是第二个元素的第二个子层。

layers.extend

追加别的list到layers当中。

nohup python my.py >> /usr/local/python/xxf/my.log 2>&1 &

nohup python -u flush.py > flush.log 2>&1 &

将python执行的日志打印到 1中,记忆方法,nohup python my.py
nohup python -u main.py >> x.log 2>&1 &
其中-u是python的命令,表示无延迟的写入到日志,>> 表示是写入文件尾部,对文件不进行覆盖,2>&1 标准输出写入,&表示后台执行。

input.detach_()

input 不可继续求导。

input.data.new(n, t, fold, h, w).zero_()

【深度学习】小技巧小知识备忘录_第1张图片
tensor.new() 方法就是创建一个类型和device类型和原来tensor完全一样的tensor,形状可以指定。

net.chidren() 和 net.modules() 的不同

-【深度学习】小技巧小知识备忘录_第2张图片

torch.matmul(a,b)

【深度学习】小技巧小知识备忘录_第3张图片

something 数据解压

cat 20bn-something-something-v2-?? | tar zx
# 其中z表示zip 解压,x : extract, v: 现实过程,f:后边必须跟文件名。

安装ffmegp

sudo add-apt-repository ppa:djcj/hybrid  
sudo apt-get update  
sudo apt-get install ffmpeg  

PIL 图像转化成为numpy 格式:

rgb_cache = Image.open("test.png").convert("RGB")
numpy_image = np.array(rgb_cache)
numpy_image.shape

【深度学习】小技巧小知识备忘录_第4张图片

暴露接口

pyton 文件开头写入如:

__all__ = ['cutmix2d',
           'cutmix3d',
           'CutMixCollator']
           

torch.randperm(n)

0 - n-1 打乱的随机序列,用来打乱索引用的。

F.one_hot(label, num_classes)

DataLoader的collate_fn

对每个batch的数据进行一个函数操作,返回一个batch的数据。

def collate_fn(batch):
    data = [item[0] for item in batch]
    # 这里对我的target进行了reshape操作
    target = [torch.reshape(item[1], (-1,)) for item in batch]
    data = torch.stack(data)
    target = torch.stack(target)
    return [data, target]

import pdb; pdb.set_trace()

用来进行手动debug 暂停的,很好用, 记忆: python debug.

torch.tensor.permute([0,2,1])

将第一个和第二个通道进行交换。

torch.split(tensor, split_size_or_sections, dim=0)

将tensor split 成 split_size 大小的块,返回的时候块数个tensor.
a = torch.rand(10,4,3)
【深度学习】小技巧小知识备忘录_第5张图片
如果第一个参数不是list,而是一个int,则会将tensor在特定维度平均分成int个tensor:
【深度学习】小技巧小知识备忘录_第6张图片

F.pad(tensor, pad, mode="constant", value=0)

对tensor 进行维度扩充,pad的大小是tensor维度数量的两倍,分别表示两个方向。
【深度学习】小技巧小知识备忘录_第7张图片
可以看出,对第一个维度进行了0扩充,并且只是在一侧进行扩充2个维度。

torch 中的几种乘法*, torch.mul, torch.mm, torch.matmul


  • *
    【深度学习】小技巧小知识备忘录_第8张图片
    【深度学习】小技巧小知识备忘录_第9张图片
    直接点成会出错。
    在这里插入图片描述

  • torch.mul(a, b) 是矩阵a和b对应位相乘,a和b的维度必须相等,比如a的维度是(1, 2),b的维度是(1, 2),返回的仍是(1, 2)的矩阵;
  • torch.mm(a, b) 是矩阵a和b矩阵相乘,比如a的维度是(1, 2),b的维度是(2, 3),返回的就是(1, 3)的矩阵。
  • torch.bmm() 强制规定维度和大小相同
  • torch.matmul() 没有强制规定维度和大小,可以用利用广播机制进行不同维度的相乘操作
    【深度学习】小技巧小知识备忘录_第10张图片

ps aux

a:显示当前终端下的所有进程信息,包括其他用户的进程。

u:使用以用户为主的格式输出进程信息。

x:显示当前用户在所有终端下的进程。


sys.path.insert(0, "../")

import 会有限检查上层目录。


np.flip(input_data, 3)

input data shape : n,h,w,c 在通道维度进行翻转,rgb到gbr


torch.nn.DataParalle() 引起的权重key值变化

def remove_module_from_checkpoint_state_dict(state_dict):
    """
    Removes the prefix `module` from weight names that gets added by
    torch.nn.DataParallel()
    """
    from collections import OrderedDict
    new_state_dict = OrderedDict()
    for k, v in state_dict.items():
        name = k[7:]  # remove `module.`
        new_state_dict[name] = v
    return new_state_dict
checkpoint["state_dict"] = remove_module_from_checkpoint_state_dict(checkpoint["state_dict"])

命令行转换图片的工具

imagemagick

$convert image.png -resize 200x200 resize.png
$convert image.png -resize 50% resize.png
$convert image.png -resize 50%  -resize 200%  resize.png 
#模糊了
#参考:https://blog.csdn.net/newborn2012/article/details/24964577


模型修改后的权重加载

model = torchvision.model.resnet18xxxx # resnet18xxx 是在原来模型上进行了很大程度的修改的。

model_state_dict = model.state_dict()
pretrained_state_dict = {xxxx}
state_dict = {k:v for k,v in pretrained_state_dict.items() if k in model_state_dict}
// dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
model_state_dict.update(state_dict)
model_state_dict = model_state_dict.update(model_state_dict)

torch.conv2d.weight shape

w shape :[outputchannels, inputchannels, kernelsize,kernelsize]

在这里插入图片描述


repeat, repeat_interleave()

在这里插入图片描述
在这里插入图片描述
根据需要不同而不同。


pd.get_dummies

【深度学习】小技巧小知识备忘录_第11张图片

【深度学习】小技巧小知识备忘录_第12张图片


sklearn.preprocessing.MinMaxScaler

scalar = MinMaxScaleer()
X = scalar.fit_transform(X)
import sklearn.preprocessing.StandardScaler()
same usage like minmaxScaler()

pandas 中数值型和离散型变量的统计信息

train_df.describe(include=[‘O’]) # 给出离散型变量的统计信息。
train_df.describe() # 给出离散型变量的统计信息。

g = sns.FacetGrid

分析不同时间的小费的收入情况:横轴是小费金额,纵轴是样本数量。
【深度学习】小技巧小知识备忘录_第13张图片

pd.cut(train_df['Age'], 5)

将一个列的只进行划分bin,构成新的列

train_df['AgeBand'] = pd.cut(train_df['Age'], 5)
train_df.drop(['AgeBand'], axis=1) # 丢弃该列,分析过后。



pandas df.mode()

返回每列频率出现最多的数据。
【深度学习】小技巧小知识备忘录_第14张图片


map 将类别特征转换为数字特征

dataset[‘Embarked’].map( {‘S’: 0, ‘C’: 1, ‘Q’: 2} )


root mean square percentage error

【深度学习】小技巧小知识备忘录_第15张图片


正则化方法来抽取字符串

\d: 表示数字
\w : 表示数字,字母。
“ * ” 表示前边的正则化任意次。
“?”表示0或者1次。
“+”表示1次以上任意次。
re{ n}: 匹配前边表达式n次。
re{n,m}:n到m次。
a| b : a或者b
[a,b] : 同理。
\W	匹配非字母数字及下划线
[]表示
\S	匹配任意非空字符
\D	匹配任意非数字

re.complie(r"\d+\.\d+")

表示浮点数正则项目 re.complie(r"(\d+.\d+)+") 表示这种数字出现若干次,用于提取一个字符串中有多个浮点数的时候。

re.findall(reg, str)

在str中寻找reg正则形式的字符段,如果re 是group形式,则返回列表。
reg如果是complie 后的正则项,也可以写成 reg.findall(str)

?P\[]

import re
# 目标字符串。
line ='192.168.0.1 25/Oct/2012:14:46:34 "GET /api HTTP/1.1" 200 44 "http://abc.com/search" "Mozilla/5.0"'
# 要寻找的子串正则表达。
# ^ 从头开始。
# (?P[^ ]*): 命名为remote_ip,非空格字符组成的字符串。【192.168.0.1】
# (?P[^ ]*) : 命名为date , 任意个非空格字符组成的字符串。【25/Oct/2012:14:46:34】
# "(?P[^"]*)" 命名为request, 引号内的内容,非引号组成的字符串。【GET /api HTTP/1.1】
# (?P[^ ]*) 命名为status, 非空格组成的字符串。 【200】
# (?P[^ ]*) 命名为size, 非空格字符串。【44】
# "(?P[^"]*)" 命名为referrer, 引号内的字符串,非引号。【http://abc.com/search】
# "(?P[^"]*)"'): 命名为user_agent, 非引号的字符串,"Mozilla/5.0"'
reg = re.compile('^(?P[^ ]*) (?P[^ ]*) "(?P[^"]*)" (?P[^ ]*) (?P[^ ]*) "(?P[^"]*)" "(?P[^"]*)"')
regMatch = reg.match(line)
linebits = regMatch.groupdict()
print(linebits)
for k, v in linebits.items() :
    print(k+": "+v)
{'remote_ip': '192.168.0.1', 'date': '25/Oct/2012:14:46:34', 'request': 'GET /api HTTP/1.1', 'status': '200', 'size': '44', 'referrer': 'http://abc.com/search', 'user_agent': 'Mozilla/5.0'}
remote_ip: 192.168.0.1
date: 25/Oct/2012:14:46:34
request: GET /api HTTP/1.1
status: 200
size: 44
referrer: http://abc.com/search
user_agent: Mozilla/5.0

pytorch random seed

seed=0

random.seed(seed)
np.random.seed(seed)
if torch.cuda.is_available():
    torch.cuda.manual_seed_all(seed)

torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)

# Remove randomness (may be slower on Tesla GPUs)
# https://pytorch.org/docs/stable/notes/randomness.html
if seed == 0:
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False

latex 表格宽度与栏同步

\begin{table}[!htbp]
\centering
\footnotesize
\caption{The seasonal indexes for each month for the SLFOASVR model.}\label{tab:4}
\begin{tabular*}{7.5cm}{@{\extracolsep{\fill}}lclc}
  \hline
  Month & Seasonal index &  Month & Seasonal index \\\hline
  January & 0.9739 & July & 1.0282 \\
  February & 0.8747 & August & 1.0302 \\
  March & 1.0293 & September & 0.9761 \\
  April & 1.0710 & October & 1.0447 \\
  May & 0.9992 & November & 0.9839 \\
  June & 0.9587 & December & 1.0299 \\
  \hline
\end{tabular*}
\end{table}

e.g. etc. et al. i.e 的意思

1)et al.

et al. 是用得最多的,一般在文中引用学者成果或者是参考文献时,罗列作者时的省略。

它的完整写法应该是 et alia,意为“等人,以及其他人”。

注:1、缩写时 et 后不要加“.”因为 et 不是缩写;

2、al 后面要加“.”因为是缩写;

3、如果et al. 在句子最后,不需要重复两个“.”;

4、如果后面跟“? !,”等标点,则还需要“.”;

5、et al. 的前面不要逗号。

如:These results agree with the ones published by Pelon et al.

`etc` : 一般将它放在列举的最后,表示前面的例子还没列举完。如:I need to go to the store and buy some pie, milk, cheese, etc.

注:1、etc. 前面要有逗号;
2、同样地,位于句尾时,不要加两个“.”
3、etc. 常常被误写为 ect.,这是因为很多英语的c在t前(c 在 t 后的很少)。
etc.et al. 的区别:
人 的场合用 “et al.”,而无生命 的场合用 “etc.”

3)e.g.

e.g. 的全称是 exampli gratia,意为“例如”。

可以代替"for example; for instance;such as"等。如: Buy some vegetables, e.g., carrots.
注:1、e 和 g 后面都有“.” 经常出现的错误是,忘记 e 后面的“.”
2、最好把 e.g. 连同它的例子放在括号中,如 I like quiet activities (e.g., reading)
3、不要在 e.g. 的列表最后再用 etc.
( 在 including 后的列表后也不宜使用 etc ),这是因为 e.g. 表示泛泛的举几个例子,并没有囊括所有的实例,其中就已经包含“等等”,如果再加一个 etc. 就多余了.
例如这是错的:Writing instructors focus on a number of complex skills that require extensive practice (e.g., organization, clear expression, logical thinking, etc.)

4)i.e.

i.e. 的全称是 id est,意为“也就是”。

相当于 “that is” , “in other words”,用于进一步解释前面所面所言。

注:1、i.e. 的第一个"." 常常容易被漏掉。

2、i.e. 后面应该有逗号。

3、与 e.g. 一样, i.e. 也最好放入括号中,如:There are three meals in the day (i.e., breakfast, lunch, and dinner).

et al. 等人(后面一个“.”)

etc. 等物(一个“.”)

e.g. 例如(前后两个“.”)

i.e. 也就是(前后两个“.”)

opencv 保存图片

cv2.imwrite(filename, img)

pytorch 输出中间特征层

mid_f = []
def mid_features(module,input,output):
    mid_f.append(output)

for name,m in model.base_model.named_modules():
        # m.register_forward_pre_hook(mid_features)
        if name == "conv1":
            m.register_forward_hook(mid_features)
with torch.no_grad():
    output = model((input_data,torch.tensor(0)))

hyperref 的超链接颜色

https://www.zhihu.com/question/29673303?sort=created

%\usepackage{hyperref}
%\hypersetup{hidelinks}

\usepackage[colorlinks,
linkcolor=red,
anchorcolor=blue,
citecolor=green]{hyperref}    
    

环境变脸备忘

F:\CTEX\UserData\miktex\bin;F:\CTEX\MiKTeX\miktex\bin;F:\CTEX\CTeX\ctex\bin;F:\CTEX\CTeX\cct\bin;F:\CTEX\CTeX\ty\bin;F:\CTEX\Ghostscript\gs9.05\bin;F:\CTEX\GSview\gsview;F:\CTEX\WinEdt;C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Anaconda3 (64-bit);F:\conda;F:\conda\Scripts;F:\conda\Library\bin;F:\conda\Library\mingw-w64\bin;%CUDA_PATH%;%NVTOOLSEXT_PATH%;%JAVA_HOME%;%NDK_HOME%;"%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;%SYSTEMROOT%\System32\OpenSSH\;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;%GOROOT%\bin;";%CUDA_PATH%\bin;%CUDA_PATH%\libnvvp;%CUDA_PATH%\lib\x64;C:\Windows\System32;C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_1c83a5d7cffd7bff;"F:\conda\envs\pytorch;F:\conda\envs\pytorch\Library\bin;F:\conda\envs\pytorch\Library\mingw-w64\bin";C:\Windows\SysWOW64;

OpenCV 与 PIL 的 Image 互转

img = cv2.cvtColor(numpy.asarray(img),cv2.COLOR_RGB2BGR)
img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))

切片超界不报错

           
class Solution:
    def oneEditAway(self, first: str, second: str) -> bool:
        # 更加简洁的解法
        m,n = len(first), len(second)
        if abs(m-n) > 1:
            return False
        for i in range(min(m,n)):
            if first[i] != second[i]:
                return first[i+1:] == second[i+1:] or first[i:] == second[i+1:] or first[i+1:] == second[i:]
                # 不会超过边界报错的原因是,如果 second[i+1], i+1 超界会报错,但是second[i+1:] 进行切片则不会报错。
        return True     

sortedcontainers

>>> from sortedcontainers import SortedList
>>> sl = SortedList(['e', 'a', 'c', 'd', 'b'])
>>> sl
SortedList(['a', 'b', 'c', 'd', 'e'])
>>> sl *= 10_000_000
>>> sl.count('c')
10000000
>>> sl[-3:]
['e', 'e', 'e']
>>> from sortedcontainers import SortedDict
>>> sd = SortedDict({'c': 3, 'a': 1, 'b': 2})
>>> sd
SortedDict({'a': 1, 'b': 2, 'c': 3})
>>> sd.popitem(index=-1)
('c', 3)
>>> from sortedcontainers import SortedSet
>>> ss = SortedSet('abracadabra')
>>> ss
SortedSet(['a', 'b', 'c', 'd', 'r'])
>>> ss.bisect_left('c')
2

Python中bisect的使用方法

bisect查找

import bisect
 
a = [1,4,6,8,12,15,20]
position = bisect.bisect(a,13)
print(position)
 
# 用可变序列内置的insert方法插入
a.insert(position,13)
print(a)

insort 插入

import bisect
 
a = [1,4,6,8,12,15,20]
bisect.insort(a,13)
print(a)

还有bisect_left, bisect_right 等方法。


heapq 的topk

from heapq import nlargest, nsmallest

class Solution:
    def minMoves2(self, nums: List[int]) -> int:
        return sum((right - left for (right, left) in zip(nlargest(len(nums)//2, nums), nsmallest(len(nums)//2, nums))))

heapq模块

a = [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25]
heapq.heapq(a)
heapq.nlargest(5, a) # 选出5个最大值。
heapq.nlargest(5, a, key=lambda x : func(x))
heapq.heappush(h, (3,"dadadada)) # 后边的字符串表示任务,前边的数字表示优先级。

保留浮点数的两位小数

  • 方法1:
a = 23.33434
print("%.2f" % a )
ax = "%.2f" % a
# 23.33
  • 方法2:
ax = round(a, 2) # 直接舍去,不考虑经度是否能够四舍五入。
  • 方法3:
ax = format(a, ".2f")

字典的setdefault() 和 pairwise() 操作

字典除了可以直接设置成为 collections.defaultdict 外,还可以如下使用,而不用判断是否有key.

g = {}
g.setdefault("a", 100) # 这种方式只能在字典中没有KEY的时候传入值,有了key值后,再用这种方式,对应的val 值是不会变化的。
Out[8]: 100
g
Out[9]: {'a': 100}
from itertools import pairwise
a = pairwise('12345') 
# 输出的a应为是 12 23 34 45

b = pairwise([1])
# b为空


dict.get(key[, value])

从字典中提取Key对应的value, 如果没有则返回value.


divmod(x, y)

返回商 和 余数 两个数。元组类型。


集合交集

A = {2, 3, 5, 4}
B = {2, 5, 100}
C = {2, 3, 8, 9, 10}

print(B.intersection(A))
print(B.intersection(C))
print(A.intersection(C))
print(C.intersection(A, B))

论文思路 1

  • 第一步:找到baseline论文
    一开始对深度学习不熟时,切勿自己蒙着头写代码。既然题主已经看了四十多篇论文,并且有了自己的idea, 那么肯定知道自己要做的方向有哪些前人写下的不错的论文, 从这些论文中挑选出一到两篇作为你的baseline,作为你的代码开端。 一般一个好的baseline有几个特点:
    1. 它一定有开源代码,而且有较完整的文档(readme)。如果它的github星蛮多的更好,说明很多人用过,质量没问题。
    2. 它发表的时间是近两到三年的。深度学习的发展速度实在过快,时间久远又没人维护的,它用的代码框架什么的可能会过时,比如我之前做colorization, 有几篇不错的都是用的caffe, 比较难拿来直接用。
    3. 它里面的公式整体较为清晰,这样方便你对照着代码来看公式,当你明白了如何把理论的公式转化为代码时,你基本就上道了。

  • 第二步:深入baseline代码
    当你找到了不错的baseline论文后,就要深入阅读、使用它的代码了。在你基础较差时,提高代码能力最好的方法绝对不是头铁地去楞写,而是阅读别人写的优质代码。阅读代码也是有诀窍的,一般分为这么几步:

步骤 方法
第一步

按照github的文档配置好你的环境。几年前配置环境其实是个蛮痛苦的事,那时候我还用caffe,简直就是噩梦,但现在配置环境变得特别傻瓜式,pytorch/tf都特别好配置。

第二步

配置好环境后,按它readme的步骤下载相应的数据,运行相应的脚本,让它的训练先能流畅地跑通。优质的开源代码基本都能跑通,如果在中间报了错,一般都是library版本不符。但如果是涉及到算法内部的问题,就要走到下一步了。

第三步

当你把开源代码跑起来或者遇到算法里的bug之后,用一个好的ide(例如pycharm)进入debug模式。在这个模式下的最大好处,就是你可以拿着实际的数据一步一步看代码,哪一步看不懂就对照论文的流程加谷歌一下API的使用方法,很多你干看看不懂的代码结合着tensor shape或者处理过后的数据的shape/value就能看懂。在这一步一步debug运行代码的过程里,其实你对深度学习完整的pipeline怎么写基本就有了一个比较好的认识。如果时间允许,建议把你找到的几篇baseline都这样跑一遍,并且写个笔记记录下大概流程。

  • 第三步:搭建你自己的pipeline
    我一般喜欢根据自己特定的任务从头搭建整个pipeline(包括数据I/O, 预处理,模型搭建,loss定义、训练与验证、测试等等),但鉴于题主刚接触深度学习代码,可以从第二步中挑选一个不错的baseline作为你的基础代码,站在它的肩膀上进行修修剪剪。一般你要做的方向虽然可以用baseline的算法,但数据集往往不同,所以在别人的基础上搭建自己的pipeline最重要的是修改数据读取和预处理部分。在这一步先不要把自己的模型加进去,用baseline的模型能跑通你自己的数据即可。

  • 第四步:将你的核心算法融入pipeline
    经过了上面三步之后,你已经对深度学习训练预测的流程有了一个比较清晰的认识,这个时候可以开始把你自己的idea加入pipeline. 一般来说你的idea无非是提出了更好的模型,或者更好的训练机制。模型或者loss你在网上一般都能找到整体架构较为类似的代码,比如你要做轻量级图像分割,那大概率可以借鉴Unet,网上一搜一大堆,按照他们的格式仿写即可。这里有个小诀窍,你搭建自己的模型搭好后可以先不放入自己的pipeline里真枪实战的训练,先生成几个随机的tensor扔进去做inference, 看看能不能跑通,输出的shape是否正确。

最后一点点建议,新手想快速入门首选pytorch, tf1.x对新手挺不友好的,而用tf2的研究人员比较少,容易找不到现成的代码。


论文思路2

如何提升自己的代码工程能力,三步走:

  • 把你这个方向最基础的论文【挑5篇,无上限】代码扒下来,一步步搞清楚在做什么,然后搞一个思维导图,每天晚上睡觉之前自己复述一遍,确保代码基础操作没问题;
  • 在1这个基础之上,挑选这个方向比较前沿的方向的论文的代码,看核心创新点,看实验细节是怎么操作的,最重要的是去看核心创新点的代码是怎么写的;在这一步,去看关键部分的代码就可以,然后分门别类记录下来,比如这个论文的改进点在attention,这个论文改进点在增加了残差等等,记住,把对应的核心代码也记录下来;
  • 有了点子,在2的基础上看有没有类似的论文代码,有的话就扒下来,魔改一下,没有的话,依靠1的基础和2的基础自己写出来;

记住,除了第一步你需要从零开始搞清楚代码在干啥,别的时候不需要重头复现,太费时间;

总而言之,多读论文,找到这个论文的创新点,然后扒下来对应的代码,然后记录下来,就是你的武器库了;


map(function, val) array,tensor

val can be numpy array or torch tensor:
【深度学习】小技巧小知识备忘录_第16张图片
【深度学习】小技巧小知识备忘录_第17张图片【深度学习】小技巧小知识备忘录_第18张图片

F.nll_loss

negtive logic loss

你可能感兴趣的:(机器学习,动手学深度学习,python,深度学习,pytorch)