timm库(PyTorchImageModels,简称timm)是一个巨大的PyTorch代码集合,已经被官方使用了。
参考:timm 视觉库中的 create_model 函数详解
p
r
e
t
r
a
i
n
e
d
\color{red}{pretrained}
pretrained
如果我们传入 pretrained=True,那么 timm 会从对应的 URL 下载模型权重参数并载入模型,只有当第一次(即本地还没有对应模型参数时)会去下载,之后会直接从本地加载模型权重参数。
model = timm.create_model('resnet34', pretrained=True)
输出:
Downloading: "https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/resnet34-43635321.pth" to /home/song/.cache/torch/hub/checkpoints/resnet34-43635321.pth
查
看
安
装
的
t
i
m
m
库
中
可
以
使
用
哪
些
模
型
:
\color{red}{查看安装的timm库中可以使用哪些模型:}
查看安装的timm库中可以使用哪些模型:
参考:Pytorch视觉模型库–timm

找到swin transformer的模型:
'swin_base_patch4_window7_224',
'swin_base_patch4_window7_224_in22k',
'swin_base_patch4_window12_384',
'swin_base_patch4_window12_384_in22k',
'swin_large_patch4_window7_224',
'swin_large_patch4_window7_224_in22k',
'swin_large_patch4_window12_384',
'swin_large_patch4_window12_384_in22k',
'swin_small_patch4_window7_224',
'swin_tiny_patch4_window7_224',

我们使用模型:vit_tiny_patch16_224
self.transformer_model = creat('vit_tiny_patch16_224', pretrained=True, num_classes=0)
打印模型结构可以发现:先经过PatchEmbed然后经历vit_tiny_patch16_224的
6
\color{red}{6}
6个Block,然后得到的是classifier 之前的特征


这里输入特征维度【b, 3, 224, 224】,输出特征维度【b,192】:


t_q_feature = self.transformer_model.forward_features(t_q_x)示例:
print("如果设置num_classes,表示重设全连接层,该操作通常用于迁移学习")
m = timm.create_model('resnet50', pretrained=True,num_classes=10)
m.eval()
o = m(torch.randn(2, 3, 224, 224))
print(f'Classification layer shape: {o.shape}')
#输出flatten层或者global_pool层的前一层的数据(flatten层和global_pool层通常接分类层)
o = m.forward_features(torch.randn(2, 3, 224, 224))
print(f'Feature shape: {o.shape}')
代码执行输出如下所示:
如果设置num_classes,表示重设全连接层,该操作通常用于迁移学习
Classification layer shape: torch.Size([2, 10])
Feature shape: torch.Size([2, 2048, 7, 7])
打印模型结构,前面的到normal都一样,最后的head Linear层发生变化(head): Linear(in_features=192, out_features=3600, bias=True)

这里输入特征维度【b, 3, 224, 224】,输出特征维度【b,3600】3600是我们修改的最后一层输出:

PS:直接修改num_classes=3600,就可以不用添加一层self.transformer_model.head了,是一样的模型结构和结果:


参考:【超详细】初学者包会的Vision Transformer(ViT)的PyTorch实现代码学习
可以看到一张图片


timm库中的features_only=True不适用于vision transformer模型,会报错:RuntimeError: features_only not implemented for Vision Transformer models.
summary(self.transformer_model, (3, 224, 224))打印网络结构RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same

关于位置编码等详细信息参考:【机器学习】详解 Vision Transformer (ViT)
ViT 中的位置编码没有采用原版 Transformer 中的
s
i
n
c
o
s
sincos
sincos 编码,而是直接设置为可学习的 Positional Encoding。对训练好的 Positional Encoding 进行可视化,如下图所示。我们可以看到,位置越接近,往往具有更相似的位置编码。此外,出现了行列结构,同一行/列中的 patch 具有相似的位置编码。

论文中也对学习到的位置编码进行了可视化,发现相近的图像块的位置编码较相似,且同行或列的位置编码也相近: 

(https://blog.csdn.net/qq_39478403/article/details/118704747)
vit论文地址:Attention Is All You Need 2016
中文讲解 李宏毅老师的视频:(强推)李宏毅2021/2022春机器学习课程、YouTube
参考:Vision Transformer(ViT)PyTorch代码全解析(附图解)

ViT的各个结构都写在了__init__()里,不再细讲,通过forward()来看ViT的整个前向传播过程(操作流程)。
class ViT(nn.Module):
def __init__(self, *, image_size, patch_size, num_classes, dim, depth, heads, mlp_dim, pool = 'cls', channels = 3, dim_head = 64, dropout = 0., emb_dropout = 0.):
super().__init__()
image_height, image_width = pair(image_size)
patch_height, patch_width = pair(patch_size)
assert image_height % patch_height == 0 and image_width % patch_width == 0, 'Image dimensions must be divisible by the patch size.'
num_patches = (image_height // patch_height) * (image_width // patch_width)
patch_dim = channels * patch_height * patch_width
assert pool in {'cls', 'mean'}, 'pool type must be either cls (cls token) or mean (mean pooling)'
self.to_patch_embedding = nn.Sequential(
Rearrange('b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1 = patch_height, p2 = patch_width),
nn.Linear(patch_dim, dim),
)
self.pos_embedding = nn.Parameter(torch.randn(1, num_patches + 1, dim)) # (1,65,1024)
self.cls_token = nn.Parameter(torch.randn(1, 1, dim))
self.dropout = nn.Dropout(emb_dropout)
self.transformer = Transformer(dim, depth, heads, dim_head, mlp_dim, dropout)
self.pool = pool
self.to_latent = nn.Identity()
self.mlp_head = nn.Sequential(
nn.LayerNorm(dim),
nn.Linear(dim, num_classes)
)
def forward(self, img): # img: (1, 3, 256, 256)
x = self.to_patch_embedding(img) # (1, 64, 1024)
b, n, _ = x.shape
cls_tokens = repeat(self.cls_token, '() n d -> b n d', b = b) # (1, 1, 1024)
x = torch.cat((cls_tokens, x), dim=1) # (1, 65, 1024)
x += self.pos_embedding[:, :(n + 1)] # (1, 65, 1024)
x = self.dropout(x) # (1, 65, 1024)
x = self.transformer(x) # (1, 65, 1024)
x = x.mean(dim = 1) if self.pool == 'mean' else x[:, 0] # (1, 1024)
x = self.to_latent(x)
return self.mlp_head(x)
整体流程:

!!!注意,经过Transformer Encoder块的输入和输出都为(b,65,1024),只不过timm中是将经过特征提取后的[:,0]出来(维度为b,1,1024)用于后续mlp head的输入。

今天看源码时,遇到的这个恒等函数,就如同名字那样
占位符,并没有实际操作
主要使用场景:
不区分参数的占位符标识运算符
if 某个操作 else Identity()
在增减网络过程中,可以使得整个网络层数据不变,便于迁移权重数据。
x = self.patch_embed(x):

x = self.patch_embed(x)内的forward函数:x = self.proj(x)后变为(b,192,14,14)x = x.flatten(2).transpose(1, 2) # BCHW -> BNC【用到了flatten(2)将BCHW -> BNC,之后变为196(1414)768(16 16 3通道)】,14*14合并为192,这个出来后变为(16,196,192)x = self.norm(x)后return

x = self.pos_drop(x + self.pos_embed)self.norm = norm_layer(embed_dim)return x[:, 0],即返回下标0的可学习的cls_token用于后续的mlp head分类
通过nn.Parameter(torch.zeros(1, 1, embed_dim))将一个不可训练的类型Tensor转换成可以训练的类型parameter并将这个parameter绑定到这个module里面(net.parameter()中就有这个绑定的parameter。详解参考:PyTorch中的torch.nn.Parameter() 详解

注意blocks中堆叠块是使用nn.Sequential(*配合下面list的用法,重复depth个Block:
[1 for i in range(5)]
Out[2]: [1, 1, 1, 1, 1]
参考:Python中的list(列表)和dict(字典)变量前面加星号*的作用
例如:
list1 = [1, 2, 3]
print(*list1)
输出:
1 2 3


x = self.norm(x)
forward_features(self, x)是forward中的第一步
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题: