热点
用户反馈管理者评Linus Torvalds:开源技术掌舵人,reasoning_content:我们要求以用户反馈管理者的口吻,写一个与技术、科技相关,关于[Linus Torvalds:开源精神奠基人与服务器开发领航者]的标题直接输出一个标题,简短精炼,30字以内nn用户反馈管理者(User Feedback Manager)的角色通常关注用户声音、反馈循环、产品改进等但这里主题是Linus Torvalds,开源精神奠基人、服务器开发领航者需要结合技术、科技,以及用户反馈管理者的视角可能可以联想到Linus对Linux内核的严格把关,接受社区反馈但又有自己的决断比如用户反馈的终极仲裁者之类的nn但要求是标题可以尝试:从用户反馈管理者角度,Linus是开源社区的最终反馈处理者标题如:Linus Torvalds:用户反馈的终极裁决者?字数:13个字加冒号?但要求30字以内或者更简洁:用户反馈管理者眼中的Linus:开源反馈的舵手?还是直接写Linus Torvalds:开源精神的用户反馈管理者?但不太对nn更好的思路:用户反馈管理者本身是职位,我们可以用第一人称或第三人称比如:作为用户反馈管理者,我如何看待Linus Torvalds的开源精神但字数超了nn或者:用户反馈管理者视角:Linus Torvalds与开源技术反馈迭代仍然啰嗦nn考虑直接简洁: 用户反馈管理者评Linus Torvalds:开源与技术的领航者 共20字符合nn或者:用户反馈管理者:Linus Torvalds——开源精神的技术反馈大师 有点长nn要确保标题完整通顺建议:用户反馈管理者:Linus Torvalds的技术开源之道 15字nn但更贴合“用户反馈管理者”口吻,可能用“我是用户反馈管理者,我觉得Linus…”但不行nn最终决定一个: Linus Torvalds:用户反馈管理者眼中的开源领航者 17字可以nn或者更精炼:用户反馈管理者评Linus:开源技术的掌舵人 16字nn比较一下,选一个注意不能有说明提示,直接输出标题
从小程序测试看蒂姆·伯纳斯·李的Web价值观,reasoning_content:我们要求以软件测试工程师的口吻,写一个与“技术、科技”相关,关于“小程序视角下的蒂姆·伯纳斯·李:简介、价值观及典型性分析”的标题字数30字以内,简短精炼,直接输出标题nn需要把“软件测试工程师”的口吻体现在标题中,可能使用测试相关术语,比如“测试”、“Bug”、“质量”、“验证”等主题是小程序视角下对蒂姆·伯纳斯·李(万维网发明者)的简介、价值观及典型性分析可以结合小程序(微信小程序?)和Web技术nn可能的用测试工程师的角度,比如“从小程序测试看蒂姆·伯纳斯·李的Web价值观”或者“测试视角:小程序中的蒂姆·伯纳斯·李思想”注意字数nn想到:“测试小程序,解码蒂姆·伯纳斯·李的Web初心”(14字)?或者“小程序视角:伯纳斯·李的技术价值观测试报告”(17字)但需要更精确nn尝试:“从小程序Bug看蒂姆·伯纳斯·李的Web哲学”(14字)或者“测试视角:蒂姆·伯纳斯·李的小程序化分析”(15字)nn更简洁:“小程序下测试蒂姆·伯纳斯·李价值观”(13字)但不够完整nn最终:思考一个直接且带测试语气的标题例如:“测试工程师谈小程序中的伯纳斯·李精神”(16字)或者“小程序测试:伯纳斯·李的Web价值观解析”(16字)nn确保不超过30字输出一个标题
移动H5视角:伯纳斯-李价值观与典型性分析,reasoning_content:我们要求以内容管理者的口吻写一个与技术、科技相关,关于[移动H5视角下的蒂姆・伯纳斯-李:简介、价值观与典型性分析]的标题要求直接输出标题,字数30字以内,简短精炼nn注意:主题是移动H5视角下分析蒂姆・伯纳斯-李(万维网发明者),包括简介、价值观、典型性标题要体现技术/科技属性,内容管理者的口吻可能更偏向内容运营、编辑视角nn可能的标题思路:结合“H5”、“伯纳斯-李”、“价值观”、“典型性”等关键词,简洁有力例如:“移动H5视角:伯纳斯-李的价值观与典型性解析” 但字数可能超?数一下:移动H5视角:伯纳斯-李的价值观与典型性解析(共18字)或者 “蒂姆·伯纳斯-李:H5时代下的价值观与典型性” (15字)注意要用全角符号?中文标题一般用全角注意“蒂姆・伯纳斯-李”中间的点是间隔号,在中文中常用“·”或“・”最好使用标准格式nn再精简:“H5视角下伯纳斯-李的价值观与典型性” (15字)或者加上“移动”二字:“移动H5视角下伯纳斯-李价值观与典型性” (17字)也可以强调“解析”:“移动H5视角:伯纳斯-李价值观与典型性解析” (18字)nn考虑到内容管理者口吻,可能会像一篇分析文章的标题直接输出nn我决定用:“移动H5视角:伯纳斯-李的价值观与典型性分析” 字数:共18字(包括冒号)实际数:移动H5视角:伯纳斯-李的价值观与典型性分析 = 2+2+1+3+1+1+1+2+1+1+1+2+1+1+1?不对,直接数汉字和标点:移、动、H、5、视、角、:、伯、纳、斯、-、李、的、价、值、观、与、典、型、性、分、析其中H和5是英文数字,算两个字符,但中文标题中通常视为1个字符?实际上在字数统计中,英文字母和数字通常算半个字?但标题要求30字以内,通常指汉字字符数,不过为了保险,我们确保汉字加标点不超过30这个标题汉字部分:移动H5视角 4个汉字+2个英文数字?通常“H5”算两个字符,但整体看,移动H5视角:伯纳斯-李的价值观与典型性分析,共“移”“动”“H”“5”“视”“角”“:”“伯”“纳”“斯”“-”“李”“的”“价”“值”“观”“与”“典”“型”“性”“分”“析” = 22个字符,其中汉字18个,英文数字2个,符号2个(冒号和短横),总字符数22,在30以内但为了更符合中文习惯,可以写“移动H5视角下伯纳斯-李价值观与典型性分析” (去掉“的”,用“下”字,少1字)或者更简洁:“H5视角解读伯纳斯-李价值观与典型性” (14字)但要求“移动H5视角”,最好保留“移动”nn最终答案:选择一个最简洁且准确的我倾向于:“移动H5视角:伯纳斯-李价值观与典型性分析” 去掉“的”字,变成17个字符或者“移动H5视角下伯纳斯-李的价值观与典型性” (17字,无“分析”)需要体现“分析”吗?原标题有“分析”,但是不一定必须内容管理者口吻,可以带“解析”、“剖析”等用“解析”代替“分析”也行nn为了保险,输出一个移动H5视角下伯纳斯-李的价值观与典型性分析数一下:移、动、H、5、视、角、下、伯、纳、斯、-、李、的、价、值、观、与、典、型、性、分、析 = 22字符OKnn或者更短:移动H5视角:伯纳斯-李价值观与典型性分析 (20字符)我选这个
葛洛夫:无障碍科技先驱的生平与价值观解析,reasoning_content:我们要求以页面编辑者的口吻,写一个与技术、科技相关,关于[无障碍先锋:史蒂夫・葛洛夫的生平、价值观及影响力解析]的标题注意标题要简短精炼,30字以内直接输出标题,不要加说明nn无障碍先锋:史蒂夫・葛洛夫他是谁?实际上史蒂夫・葛洛夫(Steve Grove)?可能是指的史蒂夫·乔布斯?不,是无障碍先锋,可能是指的史蒂夫·葛洛夫(Steve Grove)?或者拼写错误?常见的是史蒂夫·乔布斯(Steve Jobs),但这里写的是葛洛夫注意:原文是史蒂夫・葛洛夫,可能是Steve Grove?但Steve Grove不是著名科技人物也可能是史蒂夫·鲍尔默?不更可能是史蒂夫·乔布斯的误写?或者是指史蒂夫·霍夫曼?不对nn仔细看:无障碍先锋:史蒂夫・葛洛夫的生平、价值观及影响力解析 – 可能这是一个文章的标题,要求我们以页面编辑者的口吻重新写一个标题注意无障碍先锋可能是指Accessibility pioneer史蒂夫·葛洛夫?也许是指Steve Grove,他曾是Google的YouTube负责人?或者是指Steve Grubb? 不确定但为了完成任务,我们可以直接围绕无障碍先锋和科技来写标题nn既然要求以页面编辑者的口吻,可能意味着是编辑一个网页或文章标题要简短精炼,30字以内例如:科技先驱葛洛夫:无障碍先锋的价值观与影响或者更简洁:葛洛夫:无障碍科技先锋的生平与影响力注意字数nn我建议写:葛洛夫:无障碍科技先锋的生平与影响力解析但字数14个字?葛洛夫:无障碍科技先锋的生平与影响力解析 共15个字或者科技赋能无障碍:葛洛夫的生平与价值观注意原文中有史蒂夫・葛洛夫,我们可以用葛洛夫简称nn为了准确,直接输出一个标题
纯粹学术探索:Hinton的AI分类用户体验,reasoning_content:我们要求以用户体验设计师的口吻,写一个与“技术、科技”相关,关于“Geoffrey Hinton:AI分类先驱,学术探索的纯粹典范”的标题字数30字以内,直接输出标题,不要加说明nn用户体验设计师关注用户、体验、设计、交互等结合AI先驱,可以体现“技术以人为本”或“探索的纯粹性”尝试:从用户视角看Hinton的贡献比如:“AI先驱的纯粹探索:技术如何让用户更智能?”但需要30字内nn简短精炼:可能“Geoffrey Hinton:用分类重塑AI体验的纯粹学者”但字数超?计算:“Geoffrey Hinton:用分类重塑AI体验的纯粹学者”共20字?字符数:Geoffrey Hinton(14字母+空格?中文字符更简单)标题最好中文用户要求中文标题所以写中文nn例如:“纯粹探索:Geoffrey Hinton的用户体验式AI分类革命” 字数?数一下:纯粹探索:Geoffrey Hinton的用户体验式AI分类革命(共?中文字符+英文名)最好全中文?Geoffrey Hinton可保留英文名字数控制在30字内尝试:“AI分类先驱Hinton:学术纯粹的用户体验” 13字或者“Hinton:AI分类的纯粹探索,科技以人为本” 16字更符合用户设计师口吻:强调“用户体验”一词例如:“体验至上:Hinton的AI分类纯粹探索” 13字或者“科技纯粹:Hinton如何定义AI分类的用户体验” 19字再精简:“Hinton:AI分类先驱,纯粹学术体验” 12字但“用户体验设计师”口吻,可以强调“设计”、“交互”、“用户”比如:“设计纯粹:Hinton的AI分类如何塑造用户认知” 18字nn最终选择:考虑到用户要求“简短精炼”,直接输出我给出:“Geoffrey Hinton:用纯粹探索定义AI分类的用户体验” 共?中文字+英文名算字数:中文部分“用纯粹探索定义AI分类的用户体验”共14字,加英文名“Geoffrey Hinton”算14个字母,通常按汉字字数算英文名算一个词?标题中通常英文名算作几个字?最好避免歧义直接用中文名:杰弗里·辛顿但用户给的是英文名保持原样吧nn更简洁:“Hinton:AI分类的纯粹用户体验探索” 11字或者“纯粹体验:Hinton的AI分类学术探索” 12字nn我认为“Hinton:AI分类先驱,纯粹的用户体验学术” 13字或者“AI分类纯粹探索:Hinton的用户体验之道” 14字nn最佳可能:“纯粹学术探索:Hinton的AI分类用户体验” 13字nn直接输出
16 9 月 2026, 周三

副标题#e#

100行Python代码,轻松搞定神经网络

大数据文摘出品

来源:eisenjulian

编译:周家乐、钱天培

用tensorflow,pytorch这类深度学习库来写一个神经网络早就不稀奇了。

可是,你知道怎么用python和numpy来优雅地搭一个神经网络嘛?

现如今,有多种深度学习框架可供选择,他们带有自动微分、基于图的优化计算和硬件加速等各种重要特性。对人们而言,似乎享受这些重要特性带来的便利已经是理所当然的事儿了。但其实,瞧一瞧隐藏在这些特性下的东西,能更好的帮助你理解这些网络究竟是如何工作的。

所以今天,文摘菌就来手把手教大家搭一个神经网络。原料就是简单的python和numpy代码!

文章中的所有代码可以都在这儿获取。

https://colab.research.google.com/github/eisenjulian/slides/blob/master/NN_from_scratch/notebook.ipynb

符号说明

在计算反向传播时, 我们可以选择使用函数符号、变量符号去记录求导过程。它们分别对应了计算图中的边和节点来表示它们。

给定R^n→R和x∈R^n, 那么梯度是由偏导∂f/∂j(x)组成的n维行向量

如果f:R^n→R^m 和x∈R^n,那么 Jacobian矩阵是下列函数组成的一个m×n的矩阵。

对于给定的函数f和向量a和b如果a=f(b)那么我们用∂a/∂b 表示Jacobian矩阵,当a是实数时则表示梯度

链式法则

给定三个分属于不同向量空间的向量a∈A及c∈C和两个可微函数f:A→B及g:B→C使得f(a)=b和g(b)=c,我们能得到复合函数的Jacobian矩阵是函数f和g的jacobian矩阵的乘积:

这就是大名鼎鼎的链式法则。提出于上世纪60、70年代的反向传播算法就是应用了链式法则来计算一个实函数相对于其不同参数的梯度的。

要知道我们的最终目标是通过沿着梯度的相反方向来逐步找到函数的最小值 (当然最好是全局最小值), 因为至少在局部来说, 这样做将使得函数值逐步下降。当我们有两个参数需要优化时, 整个过程如图所示:

反向模式求导

假设函数fi(ai)=ai+1由多于两个函数复合而成,我们可以反复应用公式求导并得到:

可以有很多种方式计算这个乘积,最常见的是从左向右或从右向左。

如果an是一个标量,那么在计算整个梯度的时候我们可以通过先计算∂an/∂an-1并逐步右乘所有的Jacobian矩阵∂ai/∂ai-1来得到。这个操作有时被称作VJP或向量-Jacobian乘积(Vector-Jacobian Product)。

又因为整个过程中我们是从计算∂an/∂an-1开始逐步计算∂an/∂an-2,∂an/∂an-3等梯度到最后,并保存中间值,所以这个过程被称为反向模式求导。最终,我们可以计算出an相对于所有其他变量的梯度。

相对而言,前向模式的过程正相反。它从计算Jacobian矩阵如∂a2/∂a1开始,并左乘∂a3/∂a2来计算∂a3/∂a1。如果我们继续乘上∂ai/∂ai-1并保存中间值,最终我们可以得到所有变量相对于∂a2/∂a1的梯度。当∂a2/∂a1是标量时,所有乘积都是列向量,这被称为Jacobian向量乘积(或者JVP,Jacobian-Vector Product )。

你大概已经猜到了,对于反向传播来说,我们更偏向应用反向模式——因为我们想要逐步得到损失函数对于每层参数的梯度。正向模式虽然也可以计算需要的梯度, 但因为重复计算太多而效率很低。

计算梯度的过程看起来像是有很多高维矩阵相乘, 但实际上,Jacobian矩阵常常是稀疏、块或者对角矩阵,又因为我们只关心将其右乘行向量的结果,所以就不需要耗费太多计算和存储资源。

在本文中, 我们的方法主要用于按顺序逐层搭建的神经网络, 但同样的方法也适用于计算梯度的其他算法或计算图。

关于反向和正向模式的详尽描述可以参考这里☟:

http://colah.github.io/posts/2015-08-Backprop/

深度神经网络

在典型的监督机器学习算法中, 我们通常用到一个很复杂函数,它的输入是存有标签样本数值特征的张量。此外,还有很多用于描述模型的权重张量。

损失函数是关于样本和权重的标量函数, 它是衡量模型输出与预期标签的差距的指标。我们的目标是找到最合适的权重让损失最小。在深度学习中, 损失函数被表示为一串易于求导的简单函数的复合。所有这些简单函数(除了最后一个函数),都是我们指的层, 而每一层通常有两组参数: 输入 (可以是上一层的输出) 和权重。

而最后一个函数代表了损失度量, 它也有两组参数: 模型输出y和真实标签y^。例如, 如果损失度量l为平方误差, 则∂l/∂y为 2 avg(y-y^)。损失度量的梯度将是应用反向模式求导的起始行向量。

Autograd

自动求导背后的思想已是相当成熟了。它可以在运行时或编译过程中完成,但如何实现会对性能产生巨大影响。我建议你能认真阅读 HIPS autograd的 Python 实现,来真正了解autograd。

#p#副标题#e#

核心想法其实始终未变。从我们在学校学习如何求导时, 就应该知道这一点了。如果我们能够追踪最终求出标量输出的计算, 并且我们知道如何对简单操作求导 (例如加法、乘法、幂、指数、对数等等), 我们就可以算出输出的梯度。

假设我们有一个线性的中间层f,由矩阵乘法表示(暂时不考虑偏置):

为了用梯度下降法调整w值,我们需要计算梯度∂l/∂w。这里我们可以观察到,改变y从而影响l是一个关键。

每一层都必须满足下面这个条件: 如果给出了损失函数相对于这一层输出的梯度, 就可以得到损失函数相对于这一层输入(即上一层的输出)的梯度。

现在应用两次链式法则得到损失函数相对于w的梯度:

相对于x的是:

因此, 我们既可以后向传递一个梯度, 使上一层得到更新并更新层间权重, 以优化损失, 这就行啦!

动手实践

先来看看代码, 或者直接试试Colab Notebook:

https://colab.research.google.com/github/eisenjulian/slides/blob/master/NN_from_scratch/notebook.ipynb

我们从封装了一个张量及其梯度的类(class)开始。

现在我们可以创建一个layer类,关键的想法是,在前向传播时,我们返回这一层的输出和可以接受输出梯度和输入梯度的函数,并在过程中更新权重梯度。

然后, 训练过程将有三个步骤, 计算前向传递, 然后后向传递, 最后更新权重。这里关键的一点是把更新权重放在最后, 因为权重可以在多个层中重用,我们更希望在需要的时候再更新它。

  1. class Layer: 
  2.   def __init__(self): 
  3.     self.parameters = [] 
  4.  
  5.   def forward(self, X): 
  6.     """ 
  7.     Override me! A simple no-op layer, it passes forward the inputs 
  8.     """ 
  9.     return X, lambda D: D 
  10.  
  11.   def build_param(self, tensor): 
  12.     """ 
  13.     Creates a parameter from a tensor, and saves a reference for the update step 
  14.     """ 
  15.     param = Parameter(tensor) 
  16.     self.parameters.append(param) 
  17.     return param 
  18.  
  19.   def update(self, optimizer): 
  20.     for param in self.parameters: optimizer.update(param) 

标准的做法是将更新参数的工作交给优化器, 优化器在每一批(batch)后都会接收参数的实例。最简单和最广为人知的优化方法是mini-batch随机梯度下降。

  1. class SGDOptimizer(): 
  2.   def __init__(self, lr=0.1): 
  3.     self.lr = lr 
  4.  
  5.   def update(self, param): 
  6.     param.tensor -= self.lr * param.gradient 
  7.     param.gradient.fill(0) 

在此框架下, 并使用前面计算的结果后, 线性层如下所示:

  1. class Linear(Layer): 
  2.   def __init__(self, inputs, outputs): 
  3.     super().__init__() 
  4.     tensor = np.random.randn(inputs, outputs) * np.sqrt(1 / inputs) 
  5.     selfself.weights = self.build_param(tensor) 
  6.     selfself.bias = self.build_param(np.zeros(outputs)) 
  7.  
  8.   def forward(self, X): 
  9.     def backward(D): 
  10.       self.weights.gradient += X.T @ D 
  11.       self.bias.gradient += D.sum(axis=0) 
  12.       return D @ self.weights.tensor.T 
  13.     return X @ self.weights.tensor +  self.bias.tensor, backward 

#p#副标题#e##p#分页标题#e#

接下来看看另一个常用的层,激活层。它们属于点式(pointwise)非线性函数。点式函数的 Jacobian矩阵是对角矩阵, 这意味着当乘以梯度时, 它是逐点相乘的。

  1. class ReLu(Layer): 
  2.   def forward(self, X): 
  3.     mask = X > 0 
  4.     return X * mask, lambda D: D * mask 

计算Sigmoid函数的梯度略微有一点难度,而它也是逐点计算的:

  1. class Sigmoid(Layer): 
  2.   def forward(self, X): 
  3.     S = 1 / (1 + np.exp(-X)) 
  4.     def backward(D): 
  5.       return D * S * (1 - S) 
  6.     return S, backward 

当我们按序构建很多层后,可以遍历它们并先后得到每一层的输出,我们可以把backward函数存在一个列表内,并在计算反向传播时使用,这样就可以直接得到相对于输入层的损失梯度。就是这么神奇:

  1. class Sequential(Layer): 
  2.   def __init__(self, *layers): 
  3.     super().__init__() 
  4.     self.layers = layers 
  5.     for layer in layers: 
  6.       self.parameters.extend(layer.parameters) 
  7.  
  8.   def forward(self, X): 
  9.     backprops = [] 
  10.     Y = X 
  11.     for layer in self.layers: 
  12.       Y, backprop = layer.forward(Y) 
  13.       backprops.append(backprop) 
  14.     def backward(D): 
  15.       for backprop in reversed(backprops): 
  16.         D = backprop(D) 
  17.       return D 
  18.     return Y, backward 

正如我们前面提到的,我们将需要定义批样本的损失函数和梯度。一个典型的例子是MSE,它被常用在回归问题里,我们可以这样实现它:

  1. def mse_loss(Yp, Yt): 
  2.   diff = Yp - Yt 
  3.   return np.square(diff).mean(), 2 * diff / len(diff) 

就差一点了!现在,我们定义了两种层,以及合并它们的方法,下面如何训练呢?我们可以使用类似于scikit-learn或者Keras中的API。

  1. class Learner(): 
  2.   def __init__(self, model, loss, optimizer): 
  3.     self.model = model 
  4.     self.loss = loss 
  5.     self.optimizer = optimizer 
  6.  
  7.   def fit_batch(self, X, Y): 
  8.     Y_, backward = self.model.forward(X) 
  9.     L, D = self.loss(Y_, Y) 
  10.     backward(D) 
  11.     self.model.update(self.optimizer) 
  12.     return L 
  13.  
  14.   def fit(self, X, Y, epochs, bs): 
  15.     losses = [] 
  16.     for epoch in range(epochs): 
  17.       p = np.random.permutation(len(X)) 
  18.       X, Y = X[p], Y[p] 
  19.       loss = 0.0 
  20.       for i in range(0, len(X), bs): 
  21.         loss += self.fit_batch(X[i:i + bs], Y[i:i + bs]) 
  22.       losses.append(loss) 
  23.     return losses 

这就行了!如果你跟随着我的思路,你可能就会发现其实有几行代码是可以被省掉的。

这代码能用不?

#p#副标题#e#

现在可以用一些数据测试下我们的代码了。

  1. X = np.random.randn(100, 10) 
  2. w = np.random.randn(10, 1) 
  3. b = np.random.randn(1) 
  4. Y = X @ W + B 
  5.  
  6. model = Linear(10, 1) 
  7. learner = Learner(model, mse_loss, SGDOptimizer(lr=0.05)) 
  8. learner.fit(X, Y, epochs=10, bs=10) 

我一共训练了10轮。

我们还能检查学到的权重和真实的权重是否一致。

  1. print(np.linalg.norm(m.weights.tensor - W), (m.bias.tensor - B)[0]) 
  2. > 1.848553648022619e-05 5.69305886743976e-06 

好了,就这么简单。让我们再试试非线性数据集,例如y=x1x2,并且再加上一个Sigmoid非线性层和另一个线性层让我们的模型更复杂些。像下面这样:

  1. X = np.random.randn(1000, 2) 
  2. Y = X[:, 0] * X[:, 1] 
  3.  
  4. losses1 = Learner( 
  5.     Sequential(Linear(2, 1)), 
  6.     mse_loss, 
  7.     SGDOptimizer(lr=0.01) 
  8. ).fit(X, Y, epochs=50, bs=50) 
  9.  
  10. losses2 = Learner( 
  11.     Sequential( 
  12.         Linear(2, 10), 
  13.         Sigmoid(), 
  14.         Linear(10, 1) 
  15.     ), 
  16.     mse_loss, 
  17.     SGDOptimizer(lr=0.3) 
  18. ).fit(X, Y, epochs=50, bs=50) 
  19.  
  20. plt.plot(losses1) 
  21. plt.plot(losses2) 
  22. plt.legend(['1 Layer', '2 Layers']) 
  23. plt.show() 

比较单一层vs两层模型在使用sigmoid激活函数的情况下的训练损失。

最后

希望通过搭建这个简单的神经网络,你已经掌握了用python和numpy实现神经网络的基本思路。

在这篇文章中,我们只定义了三种类型的层和一个损失函数, 所以还有很多事情可做,但基本原理都相似。感兴趣的同学可以试着实现更复杂的神经网络哦!

#p#副标题#e##p#分页标题#e#

References:

  • Thinc Deep Learning Library:https://github.com/explosion/thinc
  • PyTorch Tutorial:https://pytorch.org/tutorials/beginner/nn_tutorial.html
  • Calculus on Computational Graphs:http://colah.github.io/posts/2015-08-Backprop/
  • HIPS Autograd:https://github.com/HIPS/autograd

相关报道:https://eisenjulian.github.io/deep-learning-in-100-lines/

【本文是51CTO专栏机构大数据文摘的原创文章,微信公众号“大数据文摘( id: BigDataDigest)”】

     大数据文摘二维码

戳这里,看该作者更多好文

【编辑推荐】

  1. 一行代码引发恐惧,深思提高线上代码质量的方法
  2. DeBug Python代码全靠print函数?换用这个一天2K+Star的工具吧
  3. 这里有8个流行的Python可视化工具包,你喜欢哪个?
  4. 出神入化:特斯拉AI主管、李飞飞高徒Karpathy的33个神经网络「炼丹」技巧
  5. 14个Q&A,讲述python与数据科学的“暧昧情事”

【责任编辑:赵宁宁 TEL:(010)68476606】
点赞 0

dawei

【声明】:北京站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

您错过了

用户反馈管理者评Linus Torvalds:开源技术掌舵人,reasoning_content:我们要求以用户反馈管理者的口吻,写一个与技术、科技相关,关于[Linus Torvalds:开源精神奠基人与服务器开发领航者]的标题直接输出一个标题,简短精炼,30字以内nn用户反馈管理者(User Feedback Manager)的角色通常关注用户声音、反馈循环、产品改进等但这里主题是Linus Torvalds,开源精神奠基人、服务器开发领航者需要结合技术、科技,以及用户反馈管理者的视角可能可以联想到Linus对Linux内核的严格把关,接受社区反馈但又有自己的决断比如用户反馈的终极仲裁者之类的nn但要求是标题可以尝试:从用户反馈管理者角度,Linus是开源社区的最终反馈处理者标题如:Linus Torvalds:用户反馈的终极裁决者?字数:13个字加冒号?但要求30字以内或者更简洁:用户反馈管理者眼中的Linus:开源反馈的舵手?还是直接写Linus Torvalds:开源精神的用户反馈管理者?但不太对nn更好的思路:用户反馈管理者本身是职位,我们可以用第一人称或第三人称比如:作为用户反馈管理者,我如何看待Linus Torvalds的开源精神但字数超了nn或者:用户反馈管理者视角:Linus Torvalds与开源技术反馈迭代仍然啰嗦nn考虑直接简洁: 用户反馈管理者评Linus Torvalds:开源与技术的领航者 共20字符合nn或者:用户反馈管理者:Linus Torvalds——开源精神的技术反馈大师 有点长nn要确保标题完整通顺建议:用户反馈管理者:Linus Torvalds的技术开源之道 15字nn但更贴合“用户反馈管理者”口吻,可能用“我是用户反馈管理者,我觉得Linus…”但不行nn最终决定一个: Linus Torvalds:用户反馈管理者眼中的开源领航者 17字可以nn或者更精炼:用户反馈管理者评Linus:开源技术的掌舵人 16字nn比较一下,选一个注意不能有说明提示,直接输出标题

从小程序测试看蒂姆·伯纳斯·李的Web价值观,reasoning_content:我们要求以软件测试工程师的口吻,写一个与“技术、科技”相关,关于“小程序视角下的蒂姆·伯纳斯·李:简介、价值观及典型性分析”的标题字数30字以内,简短精炼,直接输出标题nn需要把“软件测试工程师”的口吻体现在标题中,可能使用测试相关术语,比如“测试”、“Bug”、“质量”、“验证”等主题是小程序视角下对蒂姆·伯纳斯·李(万维网发明者)的简介、价值观及典型性分析可以结合小程序(微信小程序?)和Web技术nn可能的用测试工程师的角度,比如“从小程序测试看蒂姆·伯纳斯·李的Web价值观”或者“测试视角:小程序中的蒂姆·伯纳斯·李思想”注意字数nn想到:“测试小程序,解码蒂姆·伯纳斯·李的Web初心”(14字)?或者“小程序视角:伯纳斯·李的技术价值观测试报告”(17字)但需要更精确nn尝试:“从小程序Bug看蒂姆·伯纳斯·李的Web哲学”(14字)或者“测试视角:蒂姆·伯纳斯·李的小程序化分析”(15字)nn更简洁:“小程序下测试蒂姆·伯纳斯·李价值观”(13字)但不够完整nn最终:思考一个直接且带测试语气的标题例如:“测试工程师谈小程序中的伯纳斯·李精神”(16字)或者“小程序测试:伯纳斯·李的Web价值观解析”(16字)nn确保不超过30字输出一个标题

移动H5视角:伯纳斯-李价值观与典型性分析,reasoning_content:我们要求以内容管理者的口吻写一个与技术、科技相关,关于[移动H5视角下的蒂姆・伯纳斯-李:简介、价值观与典型性分析]的标题要求直接输出标题,字数30字以内,简短精炼nn注意:主题是移动H5视角下分析蒂姆・伯纳斯-李(万维网发明者),包括简介、价值观、典型性标题要体现技术/科技属性,内容管理者的口吻可能更偏向内容运营、编辑视角nn可能的标题思路:结合“H5”、“伯纳斯-李”、“价值观”、“典型性”等关键词,简洁有力例如:“移动H5视角:伯纳斯-李的价值观与典型性解析” 但字数可能超?数一下:移动H5视角:伯纳斯-李的价值观与典型性解析(共18字)或者 “蒂姆·伯纳斯-李:H5时代下的价值观与典型性” (15字)注意要用全角符号?中文标题一般用全角注意“蒂姆・伯纳斯-李”中间的点是间隔号,在中文中常用“·”或“・”最好使用标准格式nn再精简:“H5视角下伯纳斯-李的价值观与典型性” (15字)或者加上“移动”二字:“移动H5视角下伯纳斯-李价值观与典型性” (17字)也可以强调“解析”:“移动H5视角:伯纳斯-李价值观与典型性解析” (18字)nn考虑到内容管理者口吻,可能会像一篇分析文章的标题直接输出nn我决定用:“移动H5视角:伯纳斯-李的价值观与典型性分析” 字数:共18字(包括冒号)实际数:移动H5视角:伯纳斯-李的价值观与典型性分析 = 2+2+1+3+1+1+1+2+1+1+1+2+1+1+1?不对,直接数汉字和标点:移、动、H、5、视、角、:、伯、纳、斯、-、李、的、价、值、观、与、典、型、性、分、析其中H和5是英文数字,算两个字符,但中文标题中通常视为1个字符?实际上在字数统计中,英文字母和数字通常算半个字?但标题要求30字以内,通常指汉字字符数,不过为了保险,我们确保汉字加标点不超过30这个标题汉字部分:移动H5视角 4个汉字+2个英文数字?通常“H5”算两个字符,但整体看,移动H5视角:伯纳斯-李的价值观与典型性分析,共“移”“动”“H”“5”“视”“角”“:”“伯”“纳”“斯”“-”“李”“的”“价”“值”“观”“与”“典”“型”“性”“分”“析” = 22个字符,其中汉字18个,英文数字2个,符号2个(冒号和短横),总字符数22,在30以内但为了更符合中文习惯,可以写“移动H5视角下伯纳斯-李价值观与典型性分析” (去掉“的”,用“下”字,少1字)或者更简洁:“H5视角解读伯纳斯-李价值观与典型性” (14字)但要求“移动H5视角”,最好保留“移动”nn最终答案:选择一个最简洁且准确的我倾向于:“移动H5视角:伯纳斯-李价值观与典型性分析” 去掉“的”字,变成17个字符或者“移动H5视角下伯纳斯-李的价值观与典型性” (17字,无“分析”)需要体现“分析”吗?原标题有“分析”,但是不一定必须内容管理者口吻,可以带“解析”、“剖析”等用“解析”代替“分析”也行nn为了保险,输出一个移动H5视角下伯纳斯-李的价值观与典型性分析数一下:移、动、H、5、视、角、下、伯、纳、斯、-、李、的、价、值、观、与、典、型、性、分、析 = 22字符OKnn或者更短:移动H5视角:伯纳斯-李价值观与典型性分析 (20字符)我选这个