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_()
tensor.new()
方法就是创建一个类型和device类型和原来tensor完全一样的tensor,形状可以指定。
net.chidren() 和 net.modules() 的不同
-
torch.matmul(a,b)
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
暴露接口
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)
如果第一个参数不是list,而是一个int,则会将tensor在特定维度平均分成int个tensor:
F.pad(tensor, pad, mode="constant", value=0)
对tensor 进行维度扩充,pad的大小是tensor维度数量的两倍,分别表示两个方向。
可以看出,对第一个维度进行了0扩充,并且只是在一侧进行扩充2个维度。
torch 中的几种乘法*, torch.mul, torch.mm, torch.matmul
- 点*
直接点成会出错。
- 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() 没有强制规定维度和大小,可以用利用广播机制进行不同维度的相乘操作
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
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
分析不同时间的小费的收入情况:横轴是小费金额,纵轴是样本数量。
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()
返回每列频率出现最多的数据。
map 将类别特征转换为数字特征
dataset[‘Embarked’].map( {‘S’: 0, ‘C’: 1, ‘Q’: 2} )
root mean square percentage error
正则化方法来抽取字符串
\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\<name>[]
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>[^ ]*): 命名为remote_ip,非空格字符组成的字符串。【192.168.0.1】
# (?P<date>[^ ]*) : 命名为date , 任意个非空格字符组成的字符串。【25/Oct/2012:14:46:34】
# "(?P<request>[^"]*)" 命名为request, 引号内的内容,非引号组成的字符串。【GET /api HTTP/1.1】
# (?P<status>[^ ]*) 命名为status, 非空格组成的字符串。 【200】
# (?P<size>[^ ]*) 命名为size, 非空格字符串。【44】
# "(?P<referrer>[^"]*)" 命名为referrer, 引号内的字符串,非引号。【http://abc.com/search】
# "(?P<user_agent>[^"]*)"'): 命名为user_agent, 非引号的字符串,"Mozilla/5.0"'
reg = re.compile('^(?P<remote_ip>[^ ]*) (?P<date>[^ ]*) "(?P<request>[^"]*)" (?P<status>[^ ]*) (?P<size>[^ ]*) "(?P<referrer>[^"]*)" "(?P<user_agent>[^"]*)"')
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:
F.nll_loss
negtive logic loss