希望您们先看过书,再来看本 blog,否则可能会看不懂,原因是我只写书上没写或者很新奇的东西。
先引个 torch 包
import torch
x.numel() 会返回张量中元素的总数。
torch.tensor() 与 torch.Tensor() 的区别
torch.tensor() 是(当你未指定 dtype 的类型时)将 data 转化为 torch.FloatTensor、torch.LongTensor、torch.DoubleTensor 等类型,转化类型依据于 data 的类型或者 dtype 的值
直接使用 vec = torch.tensor() 会报错,可以考虑如下方案修改:
vec = torch.Tensor()
vec = torch.tensor([])
torch.Tensor() 是 torch.FloatTensor() 的别名
# vec = torch.tensor()
# TypeError: tensor() missing 1 required positional arguments: "data"
vec = torch.Tensor()
vec
tensor([])
vec = torch.tensor([])
vec
tensor([])
从下面代码可以看出,两种 tensor 函数都是开辟了新的内存空间建立张量。而且 Tensor() 函数直接转化为了浮点数。
a = [1, 2]
ida = id(a)
va = torch.Tensor(a)
idva = id(va)
va2 = torch.tensor(a)
idva2 = id(va2)
a, va, va2, ida, idva, idva2
([1, 2],
tensor([1., 2.]),
tensor([1, 2]),
140242979567568,
140242979895440,
140242979896976)
torch.randn((n, m)) 会创建一个形状为 \(n \times m\) 的张量,其中每个元素都从均值为 0,标准差为 1 的标准高斯分布(正态分布)中随机采样。
torch.randn((3, 4))
tensor([[ 0.2106, 1.6204, 2.3458, -0.0705],
[-0.2921, -0.1707, 0.1801, -1.0608],
[ 0.0082, -1.4975, 0.2525, -0.2153]])
torch.cat() 函数中,\(dim=0\) 是按照行作为轴拼接,\(dim=1\) 是按照列作为轴拼接。可以简单地将其想象为吸附在轴上。
这里可以写成 (X, Y) 或者 [X, Y] 都可以,不过官方文档以及 d2l 书中都写的 (X, Y)
X = torch.arange(12, dtype=torch.float32).reshape((3, 4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
X, Y, torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)
(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]]),
tensor([[2., 1., 4., 3.],
[1., 2., 3., 4.],
[4., 3., 2., 1.]]),
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[ 2., 1., 4., 3.],
[ 1., 2., 3., 4.],
[ 4., 3., 2., 1.]]),
tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.],
[ 4., 5., 6., 7., 1., 2., 3., 4.],
[ 8., 9., 10., 11., 4., 3., 2., 1.]]))
首先,两个张量的维度必须相等(张量的维度可以理解为张量轴的个数),对于维度没有要求,除了要 \(\ge 2\)
如果两个某一维的长度不相等,那么必定存在一个张量这一维大小等于 1.
然后复制后,进行广播
两个有趣的写法:
X[1,2] = 9 使得 \(x_{1,2} = 9\)。梦回 pascal 时代。
X[0:2, :] = 12 使得前两行的所有列都赋值为 12.
如果调用语句 Y = X + Y,那么将取消引用 Y 指向的张量,而是指向新分配的内存处的张量。
本书作者认为这种元素的操作改变内存地址不可取,原因有二:
不想总是不必要地分配内存
如果不原地更新,其他引用仍然会指向旧的内存位置,这样某些代码可能会无意中引用旧的参数。
2.1 例如如果做 Z = Y 这样地操作,那么仅仅只是将 Z 指向的位置改到和 Y 一样,而没有对 Y 的内容进行复制。
执行原地操作的方法也有两种:
Y[:] = <expression>
Y += X
另外,reshape() 也修改了内存地址。
a = torch.tensor([3.5])
a, a.item(), float(a), int(a)
(tensor([3.5000]), 3.5, 3.5, 3)
这一节主要教我们怎么用 pandas 包。但是我总觉得没啥用啊
一些有趣的函数
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2],通过位置索引获得 DataFrame 实例的值。
inputs = inputs.fillna(inputs.mean()),把 inputs 中的所有 NaN 替换为 inputs 的平均值。
inputs = pd.get_dummies(inputs, dummy_na=True),这个函数将字符串类型的都改为 one-hot 类型,最后一个形参的意思是是否 NaN 也计算在内的意思。
newdata = data.drop(data.isna().sum().idxmax(), axis=1),这个语句可以删除缺失值最多的列。
跳过(233)
向量用小写粗体表示,而元素是一个标量,因此最好不要用粗体表示元素。
这里维度这个词的明确很好:向量或轴的维度被用来表示向量或轴的长度,即向量或轴的元素数量。而张量的维度用来表示张量具有的轴数。在这个意义上,张量的某个轴的维数就是这个轴的长度。
矩阵用大写粗体 \(\boldsymbol{A}\) 表示。其中的元素有两种表示方法:
\([\boldsymbol{A}]_{ij}\),在不清楚 \([\boldsymbol{A}]_{ij}\) 是否为标量时可以使用。
\(a_{ij}\),当已知 \([\boldsymbol{A}]_{ij}\) 为标量时可以使用。
另附 markdown 加粗倾斜指令 \boldsymbol{}
张量用特殊字体的大写字母表示,如 \(\sf{X, Y, Z}\),另附 markdown 等线体指令 \sf{},表示张量元素的机制和矩阵类似。
不妨假设有一个张量 \(\sf{X}\),它的形状为 \((3,4,5)\),那么,调用 len(X) 将会返回 3,原因是它只会返回第一维的长度,而 X.shape 则会返回其整体的形状。
给定具有相同形状的任意两个张量,任意按元素二元运算的结果都将是相同形状的张量。
另外,作者举了一个有趣的例子,两个矩阵的按元素乘法称为哈达玛积(Hadamard product)(数学符号为 \(\odot\))。
某些函数除了自己的主要作用外,还具有降维的第二作用。假如现在有个张量 A = torch.arange(20, dtype=torch.float32).reshape(5,4),所以它有几个例子函数具有降维功能:
A.sum()
A.mean()
其中,它们都有一个参数 axis,表示消除哪一个轴,沿着哪一个轴做操作。
也有神奇的用法比如 A.sum(axis=[0,1]),该操作与 A.sum() 等价。
可以在做操作时保持轴数不变,sum_A = A.sum(axis=1, keepdims=True),这样可以接着做操作,比如广播。
如果想沿某个轴计算其元素的累积综合,可以调用 cumsum() 函数。
A = torch.arange(20, dtype=torch.float32).reshape(5,4)
A.cumsum(axis=0)
tensor([[ 0., 1., 2., 3.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]])
两种方式:
torch.dot(x, y)
torch.sum(x * y)
函数为:torch.mv(A, x)。很有趣,这里给出了简写很棒啊,而且也更加安全一些,因为这个函数没有广播机制。
函数为:torch.mm(A, B),这个函数同样没有广播机制。
另附一下 torch.matmul(input, other, *, out=None) 的内容:
如果两个张量都是一维的,将返回点乘(标量)。
如果两个参数都是二维的,则返回矩阵-矩阵乘积。
如果第一个参数是一维的,第二个参数是二维的,为了进行矩阵乘法,会在其维度上预加一个1。矩阵乘法后,预置的维度将被移除。
如果第一个参数是二维的,第二个参数是一维的,则返回矩阵-向量乘积。
如果两个参数都是至少一维的,并且至少有一个参数是 N 维的(其中 N>2),那么将返回一个分批的矩阵乘法。如果第一个参数是一维的,为了进行分批矩阵乘法,会在其维度上预加一个 1,然后删除。如果第二个参数是一维的,那么在它的维度上加一个 1,以便进行分批矩阵乘法,之后再删除。非矩阵(例如批)的维度是广播的(因此一定是可广播的)。例如,如果 input 是一个 \((j×1×n×n)\) 张量,other 是一个 \((k×n×n)\) 张量,out 将是一个 \((j×k×n×n)\) 张量。
请注意,广播逻辑在确定输入是否可广播时只看批维度,而不看矩阵维度。例如,如果 input 是一个 \((j×1×n×m)\) 张量,other 是一个 \((k×m×p)\) 张量,这些输入对于广播是有效的,即使最后两个维度(即矩阵维度)不同,输出将是一个 \((j×k×n×p)\) 张量。这个操作对具有稀疏布局的参数有支持。特别是矩阵-矩阵(两个参数都是2维的)支持稀疏的参数,其限制与 torch.mm() 相同
范数有如下三个性质,不妨设此时有一个向量 \(\boldsymbol{x}\),它的范数为 \(f(\boldsymbol{x})\):
\(f(\alpha \boldsymbol{x}) = |\alpha|f(\boldsymbol{x})\)
\(f(\boldsymbol{x} + \boldsymbol{y}) \le f(\boldsymbol{x}) + f(\boldsymbol{y}))\)
\(f(\boldsymbol{x}) \ge 0\)
于是原书中提到几种范数:
\(L_1\) 范数:\(||\boldsymbol{x}||_1 = \sum_{i=1}^n |x_i|\),相应的代码为 torch.abs(x).sum()
\(L_2\) 范数:\(||\boldsymbol{x}||_2 = \sqrt{\sum_{i=1}^n x_i^2}\),相应的代码为 torch.norm(x)
弗罗贝尼乌斯范数(Frobenius norm):这是一个矩阵 \(\boldsymbol{X}\) 的范数 \(||\boldsymbol{X}||_F = \sqrt{\sum_{i=1}^m \sum_{j=1}^n x_{ij}^2}\),它是矩阵所有元素的平方和的平方根。
直接用 torch.norm(X) 也可以求这个值,这个函数也可以指定以哪一位做范数,参数为 dim。
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
有没有办法跳过CSV文件的第一行,让第二行作为标题?我有一个CSV文件,第一行是日期,第二行是标题,所以我需要能够在遍历它时跳过第一行。我尝试使用slice但它会将CSV转换为数组,我真的很想将其读取为CSV,以便我可以利用header。 最佳答案 根据您的数据,您可以使用另一种方法和skip_lines-option此示例跳过所有以#开头的行require'csv'CSV.parse(DATA.read,:col_sep=>';',:headers=>true,:skip_lines=>/^#/#Markcomments!)do|
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
我们有一个目前在Rails2.3.12版和Ruby1.8.7版上运行的应用程序。我们想将我们的应用程序更新到Rails4.0和Ruby2.1.0。我们有大约200个模型和150个Controller。我想知道升级过程需要多大的努力。您还可以提供升级可以遵循的步骤。我们应该先升级Ruby然后再升级Rails还是相反? 最佳答案 您想要实现的目标将是史诗般的努力。我无法为您提供分步说明,因为不可能在一个答案中涵盖所有情况。我建议不要同时升级Ruby和Rails,而是分步升级。升级本身的复杂性是巨大的,但只要您的应用程序具有合理的测试覆盖
我正在尝试让Rails在Windows10上运行。我正在使用Ruby2.3.0和Rails4.2.6,并且暂时使用Nokogiri1.6.3。当我尝试运行railsnewdemo时,它返回错误:Anerroroccurredwhileinstallingnokogiri(1.6.7.2),andBundlercannotcontinue.Makesurethat`geminstallnokogiri-v'1.6.7.2'`succeedsbeforebundling.当我运行geminstallnokogiri-v'1.6.7.2时,我得到:ERROR:Errorinstallingn
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG