「修炼开始」一文带你入门深度学习
来源 | Jack Cui
责编 | Carol
封图 | CSDN下载自视觉中国
前言
图解 AI 算法系列教程,不仅仅是涉及深度学习基础知识,还会有强化学习、迁移学习等,再往小了讲就比如拆解目标检测算法,对抗神经网络(GAN)等等。
难度会逐渐增加,今天咱先热热身,来点轻松的,当作这个系列的开篇。
深度学习
深度学习(Deep Learning)是近年来发展十分迅速的研究领域,并且在人 工智能的很多子领域都取得了巨大的成功。从根源来讲,深度学习是机器学习的一个分支。
深度学习就是从有限样例中通过算法总结出一般性的规律,并可以应用到新的未知数据上。
比如,我们可以从一些历史病例的集合中总结出症状和疾病之间的规律。这样,当有新的病人时,我们可以利用总结出来的规律来判断这个病人得了什么疾病。
深度学习主要由上图所示的几个部分组成,想学一个深度学习算法的原理,就看它是什么样的网络结构,Loss 是怎么计算的,预处理和后处理都是怎么做的。
权重初始化和学习率调整策略、优化算法、深度学习框架就那么多,并且也不是所有都要掌握,比如深度学习框架,Pytorch 玩的溜,就能应付大多数场景。
先有个整体的认知,然后再按照这个思维导图,逐个知识点学习,最后整合到一起,你会发现,你也可以自己实现各种功能的算法了。
深度学习的主要目的是从数据中自动学习到有效的特征表示,它是怎么工作的?那得从神经元说起。
随着神经科学、认知科学的发展,我们逐渐知道人类的智能行为都和大脑活动有关。
人脑神经系统[1]是一个非常复杂的组织,包含近 860 亿个神经元,这 860 亿的神经元构成了超级庞大的神经网络。
我们知道,一个人的智力不完全由遗传决定,大部分来自于生活经验。也就是说人脑神经网络是一个具有学习能力的系统。
不同神经元之间的突触有强有弱,其强度是可以通过学习(训练)来不断改变的,具有一定的可塑性,不同的连接又形成了不同的记忆印痕。
而深度学习的神经网络,就是受人脑神经网络启发,设计的一种计算模型,它从结构、实现机理和功能上模拟人脑神经网络。
比如下图就是一个最简单的前馈神经网络,第 0 层称为输入层,最后一层称为输出层,其他中间层称为隐藏层。
那神经网络如何工作的?网络层次结构、损失函数、优化算法、权重初始化、学习率调整都是如何运作的?
反向传播给你答案。前方,高能预警!
反向传播
要想弄懂深度学习原理,必须搞定反向传播[2]和链式求导法则。
先说思维导图里的网络层级结构,一个神经网络,可复杂可简单,为了方便推导,假设,你有这样一个网络层:
第一层是输入层,包含两个神经元 i1, i2 和截距项 b1(偏置);
第二层是隐含层,包含两个神经元 h1, h2 和截距项 b2 ;
第三层是输出层 o1 和 o2 ,每条线上标的 wi 是层与层之间连接的权重,激活函数我们默认为 sigmoid 函数。
在训练这个网络之前,需要初始化这些 wi 权重,这就是权重初始化,这里就有不少的初始化方法,我们选择最简单的,随机初始化。
随机初始化的结果,如下图所示:
其中,输入数据: i1=0.05, i2=0.10;
输出数据(期望的输出) : o1=0.01, o2=0.99;
初始权重: w1=0.15, w2=0.20, w3=0.25, w4=0.30, w5=0.40, w6=0.45, w7=0.50, w8=0.55。
目标:给出输入数据 i1, i2(0.05 和 0.10),使输出尽可能与原始输出o1, o2(0.01 和 0.99)接近。
神经网络的工作流程分为两步:前向传播和反向传播。
1、前向传播
前向传播是将输入数据根据权重,计算到输出层。
1)输入层->隐藏层
计算神经元 h1 的输入加权和:
神经元后面,要跟个激活层,从而引入非线性因素,这就像人的神经元一样,让细胞处于兴奋或抑制的状态。
数学模拟的形式就是通过激活函数,大于阈值就激活,反之抑制。
常用的激活函如思维导图所示,这里以非常简单的 sigmoid 激活函数为例,它的函数形式如下:
数学公式:
使用 sigmoid 激活函数,继续计算,神经元 h1 的输出 o_h1:
同理,可计算出神经元 h2 的输出 o_h2:
2)隐藏层->输出层
计算输出层神经元 o1 和 o2 的值:
这样前向传播的过程就结束了,根据输入值和权重,我们得到输出值为[0.75136079, 0.772928465],与实际值(目标)[0.01, 0.99]相差还很远,现在我们对误差进行反向传播,更新权值,重新计算输出。
2、反向传播
前向传播之后,发现输出结果与期望相差甚远,这时候就要更新权重了。
所谓深度学习的训练(炼丹),学的就是这些权重,我们期望的是调整这些权重,让输出结果符合我们的期望。
而更新权重的方式,依靠的就是反向传播。
1)计算总误差
一次前向传播过后,输出值(预测值)与目标值(标签值)有差距,那得衡量一下有多大差距。
衡量的方法,就是用思维导图中的损失函数。
损失函数也有很多,咱们还是选择一个最简单的,均方误差(MSE loss)。
均方误差的函数公式:
根据公式,直接计算预测值与标签值的总误差:
有两个输出,所以分别计算 o1 和 o2 的误差,总误差为两者之和:
2)隐含层->输出层的权值更新
以权重参数 w5 为例,如果我们想知道 w5 对整体误差产生了多少影响,可以用整体误差对 w5 求偏导求出。
这是链式法则,它是微积分中复合函数的求导法则,就是这个:
根据链式法则易得:
下面的图可以更直观的看清楚误差是怎样反向传播的:
现在我们来分别计算每个式子的值:
计算
计算:
这一步实际上就是对sigmoid函数求导,比较简单,可以自己推导一下。
计算:
最后三者相乘:
这样我们就计算出整体误差E(total)对 w5 的偏导值。
回过头来再看看上面的公式,我们发现:
为了表达方便,用来表示输出层的误差:
因此,整体误差E(total)对w5的偏导公式可以写成:
如果输出层误差计为负的话,也可以写成:
最后我们来更新 w5 的值:
这个更新权重的策略,就是思维导图中的优化算法, 是学习率,我们这里取0.5。
如果学习率要根据迭代的次数调整,那就用到了思维导图中的学习率调整。
同理,可更新w6,w7,w8:
3)隐含层->隐含层的权值更新
方法其实与上面说的差不多,但是有个地方需要变一下,在上文计算总误差对 w5 的偏导时,是从out(o1)->net(o1)->w5,但是在隐含层之间的权值更新时,是out(h1)->net(h1)->w1,而 out(h1) 会接受 E(o1) 和 E(o2) 两个地方传来的误差,所以这个地方两个都要计算。
计算:
先计算:
同理,计算出:
两者相加得到总值:
再计算:
再计算:
最后,三者相乘:
为了简化公式,用 sigma(h1) 表示隐含层单元 h1 的误差:
最后,更新 w1 的权值:
同理,额可更新w2,w3,w4的权值:
这样误差反向传播法就完成了,最后我们再把更新的权值重新计算,不停地迭代。
在这个例子中第一次迭代之后,总误差E(total)由0.298371109下降至0.291027924。
迭代10000次后,总误差为0.000035085,输出为[0.015912196,0.984065734](原输入为[0.01,0.99]),证明效果还是不错的。
这就是整个神经网络的工作原理,如果你跟着思路,顺利看到这里。那么恭喜你,深度学习的学习算是通过了一关。
Python 实现
整个过程,可以用 Python 代码实现。
#coding:utf-8
import random
import math#
# 参数解释:
# "pd_" :偏导的前缀
# "d_" :导数的前缀
# "w_ho" :隐含层到输出层的权重系数索引
# "w_ih" :输入层到隐含层的权重系数的索引class NeuralNetwork:LEARNING_RATE = 0.5def __init__(self, num_inputs, num_hidden, num_outputs, hidden_layer_weights = None, hidden_layer_bias = None, output_layer_weights = None, output_layer_bias = None):self.num_inputs = num_inputsself.hidden_layer = NeuronLayer(num_hidden, hidden_layer_bias)self.output_layer = NeuronLayer(num_outputs, output_layer_bias)self.init_weights_from_inputs_to_hidden_layer_neurons(hidden_layer_weights)self.init_weights_from_hidden_layer_neurons_to_output_layer_neurons(output_layer_weights)def init_weights_from_inputs_to_hidden_layer_neurons(self, hidden_layer_weights):weight_num = 0for h in range(len(self.hidden_layer.neurons)):for i in range(self.num_inputs):if not hidden_layer_weights:self.hidden_layer.neurons[h].weights.append(random.random())else:self.hidden_layer.neurons[h].weights.append(hidden_layer_weights[weight_num])weight_num += 1def init_weights_from_hidden_layer_neurons_to_output_layer_neurons(self, output_layer_weights):weight_num = 0for o in range(len(self.output_layer.neurons)):for h in range(len(self.hidden_layer.neurons)):if not output_layer_weights:self.output_layer.neurons[o].weights.append(random.random())else:self.output_layer.neurons[o].weights.append(output_layer_weights[weight_num])weight_num += 1def inspect(self):print('------')print('* Inputs: {}'.format(self.num_inputs))print('------')print('Hidden Layer')self.hidden_layer.inspect()print('------')print('* Output Layer')self.output_layer.inspect()print('------')def feed_forward(self, inputs):hidden_layer_outputs = self.hidden_layer.feed_forward(inputs)return self.output_layer.feed_forward(hidden_layer_outputs)def train(self, training_inputs, training_outputs):self.feed_forward(training_inputs)# 1. 输出神经元的值pd_errors_wrt_output_neuron_total_net_input = [0] * len(self.output_layer.neurons)for o in range(len(self.output_layer.neurons)):# ∂E/∂zⱼpd_errors_wrt_output_neuron_total_net_input[o] = self.output_layer.neurons[o].calculate_pd_error_wrt_total_net_input(training_outputs[o])# 2. 隐含层神经元的值pd_errors_wrt_hidden_neuron_total_net_input = [0] * len(self.hidden_layer.neurons)for h in range(len(self.hidden_layer.neurons)):# dE/dyⱼ = Σ ∂E/∂zⱼ * ∂z/∂yⱼ = Σ ∂E/∂zⱼ * wᵢⱼd_error_wrt_hidden_neuron_output = 0for o in range(len(self.output_layer.neurons)):d_error_wrt_hidden_neuron_output += pd_errors_wrt_output_neuron_total_net_input[o] * self.output_layer.neurons[o].weights[h]# ∂E/∂zⱼ = dE/dyⱼ * ∂zⱼ/∂pd_errors_wrt_hidden_neuron_total_net_input[h] = d_error_wrt_hidden_neuron_output * self.hidden_layer.neurons[h].calculate_pd_total_net_input_wrt_input()# 3. 更新输出层权重系数for o in range(len(self.output_layer.neurons)):for w_ho in range(len(self.output_layer.neurons[o].weights)):# ∂Eⱼ/∂wᵢⱼ = ∂E/∂zⱼ * ∂zⱼ/∂wᵢⱼpd_error_wrt_weight = pd_errors_wrt_output_neuron_total_net_input[o] * self.output_layer.neurons[o].calculate_pd_total_net_input_wrt_weight(w_ho)# Δw = α * ∂Eⱼ/∂wᵢself.output_layer.neurons[o].weights[w_ho] -= self.LEARNING_RATE * pd_error_wrt_weight# 4. 更新隐含层的权重系数for h in range(len(self.hidden_layer.neurons)):for w_ih in range(len(self.hidden_layer.neurons[h].weights)):# ∂Eⱼ/∂wᵢ = ∂E/∂zⱼ * ∂zⱼ/∂wᵢpd_error_wrt_weight = pd_errors_wrt_hidden_neuron_total_net_input[h] * self.hidden_layer.neurons[h].calculate_pd_total_net_input_wrt_weight(w_ih)# Δw = α * ∂Eⱼ/∂wᵢself.hidden_layer.neurons[h].weights[w_ih] -= self.LEARNING_RATE * pd_error_wrt_weightdef calculate_total_error(self, training_sets):total_error = 0for t in range(len(training_sets)):training_inputs, training_outputs = training_sets[t]self.feed_forward(training_inputs)for o in range(len(training_outputs)):total_error += self.output_layer.neurons[o].calculate_error(training_outputs[o])return total_errorclass NeuronLayer:def __init__(self, num_neurons, bias):# 同一层的神经元共享一个截距项bself.bias = bias if bias else random.random()self.neurons = []for i in range(num_neurons):self.neurons.append(Neuron(self.bias))def inspect(self):print('Neurons:', len(self.neurons))for n in range(len(self.neurons)):print(' Neuron', n)for w in range(len(self.neurons[n].weights)):print(' Weight:', self.neurons[n].weights[w])print(' Bias:', self.bias)def feed_forward(self, inputs):outputs = []for neuron in self.neurons:outputs.append(neuron.calculate_output(inputs))return outputsdef get_outputs(self):outputs = []for neuron in self.neurons:outputs.append(neuron.output)return outputsclass Neuron:def __init__(self, bias):self.bias = biasself.weights = []def calculate_output(self, inputs):self.inputs = inputsself.output = self.squash(self.calculate_total_net_input())return self.outputdef calculate_total_net_input(self):total = 0for i in range(len(self.inputs)):total += self.inputs[i] * self.weights[i]return total + self.bias# 激活函数sigmoiddef squash(self, total_net_input):return 1 / (1 + math.exp(-total_net_input))def calculate_pd_error_wrt_total_net_input(self, target_output):return self.calculate_pd_error_wrt_output(target_output) * self.calculate_pd_total_net_input_wrt_input();# 每一个神经元的误差是由平方差公式计算的def calculate_error(self, target_output):return 0.5 * (target_output - self.output) ** 2def calculate_pd_error_wrt_output(self, target_output):return -(target_output - self.output)def calculate_pd_total_net_input_wrt_input(self):return self.output * (1 - self.output)def calculate_pd_total_net_input_wrt_weight(self, index):return self.inputs[index]# 文中的例子:nn = NeuralNetwork(2, 2, 2, hidden_layer_weights=[0.15, 0.2, 0.25, 0.3], hidden_layer_bias=0.35, output_layer_weights=[0.4, 0.45, 0.5, 0.55], output_layer_bias=0.6)
for i in range(10000):nn.train([0.05, 0.1], [0.01, 0.09])print(i, round(nn.calculate_total_error([[[0.05, 0.1], [0.01, 0.09]]]), 9))#另外一个例子,可以把上面的例子注释掉再运行一下:# training_sets = [
# [[0, 0], [0]],
# [[0, 1], [1]],
# [[1, 0], [1]],
# [[1, 1], [0]]
# ]# nn = NeuralNetwork(len(training_sets[0][0]), 5, len(training_sets[0][1]))
# for i in range(10000):
# training_inputs, training_outputs = random.choice(training_sets)
# nn.train(training_inputs, training_outputs)
# print(i, nn.calculate_total_error(training_sets))
其他
预处理和后处理就相对简单很多,预处理就是一些常规的图像变换操作,数据增强方法等。
后处理每个任务都略有不同,比如目标检测的非极大值抑制等,这些内容可以放在以后再讲。
至于深度学习框架的学习,那就是另外一大块内容了,深度学习框架是一种为了深度学习开发而生的工具,库和预训练模型等资源的总和。
我们可以用 Python 实现简单的神经网络,但是复杂的神经网络,还得靠框架,框架的使用可以大幅度降低我们的开发成本。
至于学哪种框架,看个人喜好,Pytorch 和 Tensorflow 都行。
学习资料推荐
学完本文,只能算是深度学习入门,还有非常多的内容需要深入学习。
推荐一些资料,方便感兴趣的读者继续研究。
视频:
吴恩达的深度学习公开课[3]:
https://mooc.study.163.com/university/deeplearning_ai
书籍:
《神经网络与深度学习》
《PyTorch深度学习实战》
开源项目:
Pytorch教程 1:https://github.com/yunjey/pytorch-tutorial
Pytorch教程 2:https://github.com/pytorch/tutorials
学习的积累是个漫长而又孤独的过程,厚积才能薄发,有不懂的知识就多看多想,要相信最后胜利的,是坚持下去的那个人。
参考资料
[1]
推荐深度学习书籍: 《神经网络与深度学习》
[2]反向传播: https://www.cnblogs.com/charlotte77/p/5629865.html
[3]吴恩达的深度学习公开课: https://mooc.study.163.com/university/deeplearning_ai
更多精彩推荐
为什么苹果M1芯片这么快?
实战|手把手教你用Python爬取存储数据,还能自动在Excel中可视化
【官方福利】CSDN内测师限时申请,参与赢年末礼包
程序员有钱了都干什么?买豪宅,玩跑车,上太空!| 涛滔不绝
Google回应全球宕机:磁盘满了;摩拜App昨晚正式停止服务;Docker Desktop 3.0.0发布|极客头条
相关文章:

Lucene.net中文分词探究
一、中文分词方式: 中文分词几种常用的方式: A. 单字分词 单字分词,顾名思义,就是按照中文一个字一个字地进行分词。如:我们是中国人,效果:我/们/是/中/国/人。 B. …

httpd服务相关实验
实验环境: CentOS6.8 1、连接测试: 在/etc/httpd/conf/httpd.conf telnet 172.16.252.242 80 GET /index.html HTTP/1.1 Host: 172.16.252.242 # KeepAlive: Whether or not to allow persistent connections (more than # one request per connection).…
WMI使用集锦
1.WMI简介WMI是英文Windows Management Instrumentation的简写,它的功能主要是:访问本地主机的一些信息和服务,可以管理远程计算机(当然你必须要拥有足够的权限),比如:重启,关机&…

基于Ubuntu交叉编译FFmpeg Windows SDK
写在前面 FFmpeg是一个开源且跨平台的音视频解决方案,集采集、转码、流式化为一身,项目的libavcodec编解码模块和libavformat媒体格式模块,支持非常非常丰富的编解码格式和容器封装格式,是做媒体相关开发工作必须要掌握和借鉴的一…
未来2年,程序员如何吊打高学历工程师?服气!
人工智能已成为新时代的风向标,如果你是对人工智能感兴趣的互联网工作者、大学生、研究生并期望在 AI 方向发展,建议你一定要深入学习一下人工智能。因为,未来将是人工智能的时代!为什么会有这个判断呢?第一࿰…

元素宽高的获取
elem.clientWidth/Height 获取某个元素可视区的宽高(不包括边框); elem.offsetWidth/Height 获取某个元素的宽高(计算边框); 当元素有padding值时,上面两个方法获取的值都包括padding。 doc…

VC++技术内幕(三)
C*View <- Cview <- CWnd <- Cobject C*View 两个最重要的基类:CView和CWnd,CWnd提供了C*View的”窗口属性”,CView则提供了它和应用程序框架其他部分间的联系。 在视窗内绘图: OnDraw成员函数: 是CView类中的虚成员函数…

用ASP.NET如何读取NT用户名
公司有个最近要开发一个小系统,是采用ASP.NET开发,现在被一难题卡住了. 需实现功能: 用户登录进来后系统自动取得用户名,这样就不用用户再登录了, 方便用户使用,并根据用户名取他的权限. 难点: 现在读NT用户名读不倒. 折腾了大半…
《赛博朋克2077》是捏脸游戏?上科大学生社团开发了一款赛博“滤镜”
作者 | eEhyQx出品 | AI科技大本营现象级大作《赛博朋克2077》终于没有跳票顺利发布了!你通关了吗?来自上海科技大学的学生社团GeekPie打造了一款全新的“滤镜”,CyberMe。只需上传一张照片,一秒将你带入夜之城!上传一…

vue父组件调用子组件的方法
vue组件与组件通信有如下几种情况: 平行组件父组件与子组件子组件与父组件它们之间通信有几种方法有: props自定义事件vuex今天我们聊一下父组件调用子组件的一种方法 parent.vue <template><div><h1>我是父组件</h1><child …
Ajax无刷新实现图片切换特效
1.页面cs代码usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Web;usingSystem.Web.Security;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Web.UI.WebControls.WebParts;usingSystem.Web.UI.HtmlControls;usingAjaxPro;publicpartial…

授权管理【学习笔记】《卓有成效的管理者》 第二章 掌握自己的时间
每日一贴,今天的内容关键字为授权管理 比拟《领导力》那本书,德鲁克这本书可操作性更强一些。 管理别人之前,先管理好自己;管理好自己,首先是管理好自己的时光。其实个人时光管理,有专门的书籍,在公司里&am…
再不参与就晚了!!2020年结束前最后一波内测福利!人人有份!
各位程序猿们都下载CSDN官方出品的插件了吧?什么?还有不知道插件是什么的同学??你错过了太多!更酷更高效的浏览器插件,一键万能操作,新标签页极简个性,让你的工作效率UP UP UP&#…

Node.js Express 框架 Express
Express 简介 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。 使用 Express 可以快速地搭建一个完整功能的网站。 Express 框架核心特性: 可以设置中间件来响应 HTTP 请求。 定义…
Ajax实现无刷新树
1.建立一个aspx页面html代码<html xmlns"http://www.w3.org/1999/xhtml"><head id"Head1"runat"server"><title>小山</title><link type"text/css"href"../../Styles/tree_css/tree.css"rel&quo…
GEMM性能提升200倍,AutoKernel算子优化工具正式开源
作者 | OPEN AI LAB 研究员 吕春莹出品 | AI科技大本营头图 | CSDN下载自视觉中国随着AI技术的快速发展,深度学习在各个领域得到了广泛应用。深度学习模型能否成功在终端落地应用,满足产品需求,一个关键的指标就是神经网络模型的推理性能。于…

MySQL的log_bin和sql_log_bin 到底有什么区别?
2019独角兽企业重金招聘Python工程师标准>>> log_bin:二进制日志。 二进制日志的作用: 1:数据恢复 如果你的数据库出问题了,而你之前有过备份,那么可以看日志文件,找出是哪个命令导致你的数据库出问题了&a…
Ajax实现在textbox中输入内容,动态从数据库中模糊查询显示到下拉框中
功能:在textbox中输入内容,动态从数据库模糊查询显示到下拉框中,以供选择1.建立一aspx页面,html代码 <HTML><HEAD><title>WebForm1</title><SCRIPT language"javascript">//城市-------…
数据连接linux网络编程之TCP/IP基础(四):TCP连接的建立和断开、滑动窗口
在写这篇文章之前,xxx已经写过了几篇关于改数据连接主题的文章,想要了解的朋友可以去翻一下之前的文章 一、TCP段格式: TCP的段格式如下图所示 源端口号与目标端口号 源端口号和目标端口号,加上IP首部的源IP地址和目标IP地址唯一确定一个TCP连…
鲲鹏高校行太原站来袭,两大课程一站式掌握未来潮流
未来是算力比拼的时代,也是属于象牙塔中莘莘学子们的时代。北京时间12月14日,为了进一步培养计算产业人才,拓展鲲鹏产业生态影响力,由中北大学信息商务学院主办,山西鲲鹏生态创新中心承办的鲲鹏高校行系列活动在中北大…

R语言通过loess去除某个变量对数据的影响
当我们想研究不同sample的某个变量A之间的差异时,往往会因为其它一些变量B对该变量的固有影响,而影响不同sample变量A的比较,这个时候需要对sample变量A进行标准化之后才能进行比较。标准化的方法是对sample 的 A变量和B变量进行loess回归&am…
Ajax实现DataGrid/DataList动态ToolTip
1.建立一aspx页面,html代码2.cs代码 usingSystem.Data.SqlClient;usingSystem.IO;protectedvoidPage_Load(objectsender, EventArgs e) { if (!Page.IsPostBack) { BindData(); } if (ID ! "") …
语言模型自然语言处理[置顶] 哥伦比亚大学 自然语言处理 公开课 授课讲稿 翻译(四)...
每日一贴,今天的内容关键字为语言模型自然语言处理 媒介:灵机一动看了一个自然语言处理公开课,大牛柯林斯讲解的。认为很好,就自己动手把它的讲稿翻译成中文。一方面,希望通过这个翻译过程,让自己更加理解大牛的讲解内…

腾讯天衍实验室夺世界机器人大赛双冠军,新算法突破脑机接口瓶颈
日前,“2020世界机器人大赛-BCI脑控机器人大赛”公布成绩,腾讯天衍实验室和天津大学高忠科教授团队组成的C2Mind战队,经过多轮赛程的激烈比拼,实力入围BCI脑控机器人大赛“运动想象范式”赛题决赛,最终成功斩获技术赛“…

免费的私人代码托管(bitbucket) 和 常用git指令
转自 http://blog.csdn.net/nzing/article/details/24452475 今天想找个免费的私人代码托管平台,github,googlecode, SourceForge都不行,后来发现bitbucket(https://bitbucket.org/),注册时,如果不多于5个人…
Ajax简单示例之改变下拉框动态生成表格
1.建立一个aspx页面,html代码<html xmlns"http://www.w3.org/1999/xhtml"><head runat"server"><title>Untitled Page</title><script type"text/javascript">var xmlHttp; function createXML…

for语句内嵌例题与个人理解
例题1:画出一个高度为3的等腰三角形. 编写程序: #include<stdio.h> main() { int a,b,c,h; h3; \\h为高度,赋值常量3. for(a1;a<h;a) …

2020百度云秀最新成绩单,AI Cloud活跃客户数同比去年增长65%
12月17日,“ABC SUMMIT 2020百度云智峰会”在北京举行。大会以“智者先行”为主题,百度CTO王海峰展现了518新战略后百度智能云取得的最新成绩和产业智能化成果。“云智一体”成百度智能云独特的竞争力,在各行各业加快规模化落地。本届大会首次…

构建之法读后感part6
这个星期看完了构建之法的第六章,看了第六章之后了解到敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。在敏捷 开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备…
Ajax实现无刷新三联动下拉框
1.html代码<HTML><HEAD><title>Ajax实现无刷新三联动下拉框</title><meta content"Microsoft Visual Studio .NET 7.1"name"GENERATOR"><meta content"C#"name"CODE_LANGUAGE"><meta content&…