2018-01-03 21:00:50 Tong_T 阅读数 53594
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2861 人正在学习 去看看 王而川

机器学习算法已经基本学习完了,在这一系列,佛爷将开始着手学习深度学习的各种算法和应用,由于本身难度偏大,我会不定期的更新,基本清楚和更加深入的研究深度学习。代码方面我基本会使用Tensorflow框架去写,原生代码我尽力去完成,查看资料,看看自己能不能搞定。完成的例子和项目,尽量我会设计一个别人都没有实现和想到的项目。因为但凡学习深度学习的同学,一上来肯定会遇到手写数字识别,这是基础。遇到MNIST数据集。
今天这一篇文章就介绍深度学习到底是什么?

什么是深度学习?(Deep Learning)

  • 深度学习是基于机器学习延伸出来的一个新的领域,由以人大脑结构为启发的神经网络算法为起源加之模型结构深度的增加发展,并伴随大数据和计算能力的提高而产生的一系列新的算法。
    这里写图片描述

深度学习什么时间段发展起来的?

  • 其概念由著名科学家Geoffrey Hinton等人在2006年和2007年在《Sciences》等上发表的文章被提出和兴起。
    这里写图片描述这里写图片描述

深度学习能用来干什么?为什么近年来引起如此广泛的关注?

  • 深度学习,作为机器学习中延伸出来的一个领域,被应用在图像处理与计算机视觉,自然语言处理以及语音识别等领域。自2006年至今,学术界和工业界合作在深度学习方面的研究与应用在以上领域取得了突破性的进展。以ImageNet为数据库的经典图像中的物体识别竞赛为例,击败了所有传统算法,取得了前所未有的精确度。
    这里写图片描述这里写图片描述

深度学习目前有哪些代表性的学术机构和公司走在前沿?人才需要如何?

  • 学校以多伦多大学,纽约大学,斯坦福大学为代表,工业界以Google, Facebook, 和百度为代表走在深度学习研究与应用的前沿。Google挖走了Hinton,Facebook挖走了LeCun,百度硅谷的实验室挖走了Andrew Ng,Google去年4月份以超过5亿美金收购了专门研究深度学习的初创公司DeepMind, 深度学习方因技术的发展与人才的稀有造成的人才抢夺战达到了前所未有激烈的程度。诸多的大大小小(如阿里巴巴,雅虎)等公司也都在跟进,开始涉足深度学习领域,深度学习人才需求量会持续快速增长。
    这里写图片描述

深度学习如今和未来将对我们生活造成怎样的影响?

  • 目前我们使用的Android手机中google的语音识别,百度识图,google的图片搜索,都已经使用到了深度学习技术。Facebook在去年名为DeepFace的项目中对人脸识别的准备率第一次接近人类肉眼(97.25% vs 97.5%)。大数据时代,结合深度学习的发展在未来对我们生活的影响无法估量。保守而言,很多目前人类从事的活动都将因为深度学习和相关技术的发展被机器取代,如自动汽车驾驶,无人飞机,以及更加职能的机器人等。深度学习的发展让我们第一次看到并接近人工智能的终极目标。
    这里写图片描述这里写图片描述这里写图片描述

深度学习范畴
这里写图片描述

深度学习基本模型
这里写图片描述

深度学习与传统机器学习
这里写图片描述

深度学习系列参考资料来源:

  1. 深度学习进阶:算法与应用(https://www.youtube.com/playlist?list=PLO5e_-yXpYLDyeADG7xbFaJxvYyeAjHah
  2. 莫烦 Python(https://morvanzhou.github.io/):一个志同道合的机器学习爱好者。
  3. 《TensorFlow实战Google深度学习框架》才云科技 郑泽宇 顾思宇 著
    (顺带手附上彩云科技的在bitTiger平台上的招聘视频【https://www.youtube.com/watch?v=ow4NQR4fdDA】)
2016-09-21 14:52:12 qiuqinjun 阅读数 1014
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2861 人正在学习 去看看 王而川

在上篇博文中,我们介绍了深度学习算法的实现,并且以MNIST手写数字识别为例,验证了该算法的有效性。

但是我们学习逻辑回归算法的目的是解决我们的实际问题,而不是学习算法本身。逻辑回归算法在实际中的应用还是很广泛的,例如在医学领域的疾病预测中,我们就可以列出一系疾病相关因素,然后根据某位患者的具体情况,应用逻辑回归算法,判断该患者是否患有某种疾病。当然,逻辑回归算法还是有局限性的,其比较适合于处理线性可分的分类问题,但是对于线性不可分的分类问题,这种算法的价值就会大打折扣了。但是我们可以将逻辑回归算法,视为没有隐藏层的前馈网络,通过增加隐藏层,就可以处理各种线性不可分问题了。借助于Theano的框架,在后面博文中我们会介绍BP网络、多层卷积网络(LeNet),大家可以看到,在Theano中,实现这些模型是一件非常简单的事情。

言归正传,如果我们要用逻辑回归算法解决实际问题,我们主要需要改变的就是load_data函数,使其从我们规定的数据源中读取数据。在此,我们先设计一个训练数据读入的工具类SegLoader,文件名为seg_loader.py,代码如下所示:

[python] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. from __future__ import print_function  
  2.   
  3. __docformat__ = 'restructedtext en'  
  4.   
  5. import six.moves.cPickle as pickle  
  6. import gzip  
  7. import os  
  8. import sys  
  9. import timeit  
  10.   
  11. import numpy  
  12.   
  13. import theano  
  14. import theano.tensor as T  
  15.   
  16. class SegLoader(object):  
  17.     def load_data(self, dataset):  
  18.         samplesNumber = 6  
  19.         features = 2  
  20.         train_set = (numpy.ndarray(shape=(samplesNumber, features), dtype=numpy.float32), numpy.ndarray(shape=(samplesNumber), dtype=int))  
  21.         self.prepare_dataset(train_set)  
  22.         valid_set = (train_set[0].copy(), train_set[1].copy())  
  23.         test_set = (train_set[0].copy(), train_set[1].copy())  
  24.         test_set_x, test_set_y = self.shared_dataset(test_set)  
  25.         valid_set_x, valid_set_y = self.shared_dataset(valid_set)  
  26.         train_set_x, train_set_y = self.shared_dataset(train_set)  
  27.         rval = [(train_set_x, train_set_y), (valid_set_x, valid_set_y),  
  28.             (test_set_x, test_set_y)]  
  29.         return rval  
  30.   
  31.     def shared_dataset(self, data_xy, borrow=True):  
  32.         data_x, data_y = data_xy  
  33.         shared_x = theano.shared(numpy.asarray(data_x,  
  34.                                                dtype=theano.config.floatX),  
  35.                                  borrow=borrow)  
  36.         shared_y = theano.shared(numpy.asarray(data_y,  
  37.                                                dtype=theano.config.floatX),  
  38.                                  borrow=borrow)  
  39.         return shared_x, T.cast(shared_y, 'int32')  
  40.   
  41.     def prepare_dataset(self, dataset):  
  42.         dataset[0][0][0] = 1.0  
  43.         dataset[0][0][1] = 1.0  
  44.         dataset[1][0] = 1  
  45.   
  46.         dataset[0][1][0] = 2.0  
  47.         dataset[0][1][1] = 2.0  
  48.         dataset[1][1] = 1  
  49.   
  50.         dataset[0][2][0] = 3.0  
  51.         dataset[0][2][1] = 3.0  
  52.         dataset[1][2] = 1  
  53.   
  54.         dataset[0][3][0] = 1.5  
  55.         dataset[0][3][1] = 2.0  
  56.         dataset[1][3] = 0  
  57.   
  58.         dataset[0][4][0] = 2.5  
  59.         dataset[0][4][1] = 4.0  
  60.         dataset[1][4] = 0  
  61.   
  62.         dataset[0][5][0] = 3.5  
  63.         dataset[0][5][1] = 7.0  
  64.         dataset[1][5] = 0  
上面的代码非常简单,生成一个元组train_set,包含两个元素,第一个元素是一个类型为float32的二维数组,每行代表一个样本,第一列代表X坐标,第二列代表Y坐标,train_set元组的第二个元素为一维整数数组,每个元素代表一个样本的分类结果,这里有两个大类,1代表在Y=X的直线上,0代表不在该直线上,prepare_dataset准备了6个训练样。因为这个问题非常简单,所以6个样本基本就够用了,但是对实际问题而言,显然需要相当大的样本量。

接着我们定义这个线性分割的执行引擎LrSegEngine,源码文件为lr_seg_engine.py,代码如下所示:

[python] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. from __future__ import print_function  
  2.   
  3. __docformat__ = 'restructedtext en'  
  4.   
  5. import six.moves.cPickle as pickle  
  6. import gzip  
  7. import os  
  8. import sys  
  9. import timeit  
  10.   
  11. import numpy  
  12.   
  13. import theano  
  14. import theano.tensor as T  
  15. from logistic_regression import LogisticRegression  
  16. from seg_loader import SegLoader  
  17.   
  18. class LrSegEngine(object):  
  19.     def __init__(self):  
  20.         print("Logistic Regression MNIST Engine")  
  21.         self.learning_rate = 0.13  
  22.         self.n_epochs = 1000  
  23.         self.batch_size = 1 # 600  
  24.         self.dataset = 'mnist.pkl.gz'  
  25.   
  26.     def train(self):  
  27.         print("Yantao:train the model")  
  28.         loader = SegLoader()  
  29.         datasets = loader.load_data(self.dataset)  
  30.         train_set_x, train_set_y = datasets[0]  
  31.         valid_set_x, valid_set_y = datasets[1]  
  32.         test_set_x, test_set_y = datasets[2]  
  33.         n_train_batches = train_set_x.get_value(borrow=True).shape[0] // self.batch_size  
  34.         n_valid_batches = valid_set_x.get_value(borrow=True).shape[0] // self.batch_size  
  35.         n_test_batches = test_set_x.get_value(borrow=True).shape[0] // self.batch_size  
  36.         index = T.lscalar()  
  37.         x = T.matrix('x')  
  38.         y = T.ivector('y')  
  39.         # in:x,y out: 1 in y=x otherwise 0  
  40.         classifier = LogisticRegression(input=x, n_in=2, n_out=2)  
  41.         cost = classifier.negative_log_likelihood(y)  
  42.         test_model = theano.function(  
  43.             inputs=[index],  
  44.             outputs=classifier.errors(y),  
  45.             givens={  
  46.                 x: test_set_x[index * self.batch_size: (index + 1) * self.batch_size],  
  47.                 y: test_set_y[index * self.batch_size: (index + 1) * self.batch_size]  
  48.             }  
  49.         )  
  50.         validate_model = theano.function(  
  51.             inputs=[index],  
  52.             outputs=classifier.errors(y),  
  53.             givens={  
  54.                 x: valid_set_x[index * self.batch_size: (index + 1) * self.batch_size],  
  55.                 y: valid_set_y[index * self.batch_size: (index + 1) * self.batch_size]  
  56.             }  
  57.         )  
  58.         g_W = T.grad(cost=cost, wrt=classifier.W)  
  59.         g_b = T.grad(cost=cost, wrt=classifier.b)  
  60.         updates = [(classifier.W, classifier.W - self.learning_rate * g_W),  
  61.                (classifier.b, classifier.b - self.learning_rate * g_b)]  
  62.         train_model = theano.function(  
  63.             inputs=[index],  
  64.             outputs=cost,  
  65.             updates=updates,  
  66.             givens={  
  67.                 x: train_set_x[index * self.batch_size: (index + 1) * self.batch_size],  
  68.                 y: train_set_y[index * self.batch_size: (index + 1) * self.batch_size]  
  69.             }  
  70.         )  
  71.         patience = 5000    
  72.         patience_increase = 2    
  73.         improvement_threshold = 0.995    
  74.         validation_frequency = min(n_train_batches, patience // 2)  
  75.         best_validation_loss = numpy.inf  
  76.         test_score = 0.  
  77.         start_time = timeit.default_timer()  
  78.         done_looping = False  
  79.         epoch = 0  
  80.         while (epoch < self.n_epochs) and (not done_looping):  
  81.             epoch = epoch + 1  
  82.             for minibatch_index in range(n_train_batches):  
  83.                 minibatch_avg_cost = train_model(minibatch_index)  
  84.                 # iteration number  
  85.                 iter = (epoch - 1) * n_train_batches + minibatch_index  
  86.                 if (iter + 1) % validation_frequency == 0:  
  87.                     # compute zero-one loss on validation set  
  88.                     validation_losses = [validate_model(i)  
  89.                                      for i in range(n_valid_batches)]  
  90.                     this_validation_loss = numpy.mean(validation_losses)  
  91.                     print(  
  92.                         'epoch %i, minibatch %i/%i, validation error %f %%' %  
  93.                         (  
  94.                             epoch,  
  95.                             minibatch_index + 1,  
  96.                             n_train_batches,  
  97.                             this_validation_loss * 100.  
  98.                         )  
  99.                     )  
  100.                     if this_validation_loss < best_validation_loss:  
  101.                         #improve patience if loss improvement is good enough  
  102.                         if this_validation_loss < best_validation_loss * improvement_threshold:  
  103.                             patience = max(patience, iter * patience_increase)  
  104.                         best_validation_loss = this_validation_loss  
  105.                         # test it on the test set  
  106.                         test_losses = [test_model(i)  
  107.                                    for i in range(n_test_batches)]  
  108.                         test_score = numpy.mean(test_losses)  
  109.                         print(  
  110.                             (  
  111.                                 '     epoch %i, minibatch %i/%i, test error of'  
  112.                                 ' best model %f %%'  
  113.                             ) %  
  114.                             (  
  115.                                 epoch,  
  116.                                 minibatch_index + 1,  
  117.                                 n_train_batches,  
  118.                                 test_score * 100.  
  119.                             )  
  120.                         )  
  121.                         # save the best model  
  122.                         with open('best_model.pkl''wb') as f:  
  123.                             pickle.dump(classifier, f)  
  124.                 if patience <= iter:  
  125.                     done_looping = True  
  126.                     break  
  127.         end_time = timeit.default_timer()  
  128.         print(  
  129.             (  
  130.                 'Optimization complete with best validation score of %f %%,'  
  131.                 'with test performance %f %%'  
  132.             )  
  133.             % (best_validation_loss * 100., test_score * 100.)  
  134.         )  
  135.         print('The code run for %d epochs, with %f epochs/sec' % (  
  136.             epoch, 1. * epoch / (end_time - start_time)))  
  137.         print(('The code for file ' +  
  138.                os.path.split(__file__)[1] +  
  139.                ' ran for %.1fs' % ((end_time - start_time))), file=sys.stderr)  
  140.   
  141.     def run(self, data):  
  142.         print("run the model")  
  143.         classifier = pickle.load(open('best_model.pkl''rb'))  
  144.         predict_model = theano.function(  
  145.             inputs=[classifier.input],  
  146.             outputs=classifier.y_pred  
  147.         )  
  148.         rst = predict_model(data)  
  149.         print(rst)  
在这里的train方法,与上篇博文处理MNIST手写数字识别的代码基本一致,只需要注意以下几点:首先,由于我们只有6个样本,因此将样本批次的大小设置为1(在MNIST手写数字识别中,由于有6万个训练样本,所以批次大小为600);其次,在初始化逻辑回归模型时,输入维度n_in,设置为2,表示样本只有两个特征即x,y坐标,输出维度也为2,表示有两个类别,1是在y=x线上,0代表不在线上。

接着我们定义逻辑回归模型类LogisticRegression,源码文件为logistic_regression.py,代码如下所示:

[python] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. from __future__ import print_function  
  2.   
  3. __docformat__ = 'restructedtext en'  
  4.   
  5. import six.moves.cPickle as pickle  
  6. import gzip  
  7. import os  
  8. import sys  
  9. import timeit  
  10.   
  11. import numpy  
  12.   
  13. import theano  
  14. import theano.tensor as T  
  15.   
  16. class LogisticRegression(object):    
  17.     def __init__(self, input, n_in, n_out):    
  18.         self.W = theano.shared(    
  19.             value=numpy.zeros(    
  20.                 (n_in, n_out),    
  21.                 dtype=theano.config.floatX    
  22.             ),    
  23.             name='W',    
  24.             borrow=True    
  25.         )    
  26.         self.b = theano.shared(    
  27.             value=numpy.zeros(    
  28.                 (n_out,),    
  29.                 dtype=theano.config.floatX    
  30.             ),    
  31.             name='b',    
  32.             borrow=True    
  33.         )    
  34.         self.p_y_given_x = T.nnet.softmax(T.dot(input, self.W) + self.b)    
  35.         self.y_pred = T.argmax(self.p_y_given_x, axis=1)    
  36.         self.params = [self.W, self.b]    
  37.         self.input = input    
  38.         print("Yantao: ***********************************")  
  39.     
  40.     def negative_log_likelihood(self, y):    
  41.         return -T.mean(T.log(self.p_y_given_x)[T.arange(y.shape[0]), y])    
  42.     
  43.     def errors(self, y):    
  44.         if y.ndim != self.y_pred.ndim:    
  45.             raise TypeError(    
  46.                 'y should have the same shape as self.y_pred',    
  47.                 ('y', y.type, 'y_pred'self.y_pred.type)    
  48.             )    
  49.         if y.dtype.startswith('int'):    
  50.             return T.mean(T.neq(self.y_pred, y))    
  51.         else:    
  52.             raise NotImplementedError()    
上面的代码与上篇博文几乎没有变化,只是将其单独保存到一个文件中而已。

接下来是模型训练lr_train.py,代码如下所示:

[python] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. from __future__ import print_function  
  2.   
  3. __docformat__ = 'restructedtext en'  
  4.   
  5. import six.moves.cPickle as pickle  
  6. import gzip  
  7. import os  
  8. import sys  
  9. import timeit  
  10.   
  11. import numpy  
  12.   
  13. import theano  
  14. import theano.tensor as T  
  15.   
  16. from logistic_regression import LogisticRegression  
  17. from seg_loader import SegLoader  
  18. from lr_seg_engine import LrSegEngine  
  19.   
  20. if __name__ == '__main__':  
  21.     engine = LrSegEngine()  
  22.     engine.train()  
上面代码只是简单调用逻辑回归分割的引擎类的train方法,完成对模型的训练,其会将最佳的结果保存到best_model.pkl文件中。

当模型训练好之后,我们就可以拿模型来进行分类了,lr_run.py的代码如下所示:

[python] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. from seg_loader import SegLoader  
  2. from lr_seg_engine import LrSegEngine  
  3.   
  4. if __name__ == '__main__':  
  5.     print("test program v1.0")  
  6.     engine = LrSegEngine()  
  7.     data = [[2.02.0]]  
  8.     print(data)  
  9.     engine.run(data)  
上面代码首先初始化一个二维数组,其中只有一个样本元素,坐标为(2.0, 2.0),然后调用逻辑回归分割引擎的run方法,其将给出分类结果,运行这个程序,会得到类似如下所示的结果:

test program v1.0

Logistic Regression MNIST Engine

[[2.0, 2.0]]

run the model

[1]

2017-05-02 16:00:04 lqfarmer 阅读数 1403
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2861 人正在学习 去看看 王而川

推荐一套深度学习视频教程,以下是视频部分截图:


百度云下载地址:https://pan.baidu.com/s/1nuMsYZB

扫描博客头像关注微信公众号“深度学习与NLP”,回复:”视频教程"或“密码”即可获得密码

2015-10-28 14:17:57 zhang0311 阅读数 10895
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2861 人正在学习 去看看 王而川

1.       深度学习

        深度学习是机器学习研究中的一个新的领域,其动机在于建立、模拟人脑进行分析学习的神经网络,它模仿人脑的机制来解释数据,例如图像,声音和文本。深度学习典型应用为图像识别和语音识别。(由于本人不是深度学习专业人士,对深度学习理论知识不多介绍,说多了就班门弄斧了,后面主要介绍下这些深度学习算法如何进行并行化设计和优化)

2.       CPU+GPU异构协同计算简介

         近年来,计算机图形处理器(GPU,GraphicsProcess Unit)正在以大大超过摩尔定律的速度高速发展(大约每隔半年 GPU 的性能增加一倍),远远超过了CPU 的发展速度。

         CPU+GPU异构协同计算模式(图1),利用CPU进行复杂逻辑和事务处理等串行计算,利用 GPU 完成大规模并行计算,即可以各尽其能,充分发挥计算系统的处理能力。

图1 CPU+GPU异构体系结构

        目前,主流的GPU具有强大的计算能力和内存带宽,如图2所示,无论性能还是内存带宽,均远大于同代的CPU。对于GPU, Gflop/$和Gflops/w均高于CPU。

图2 GPU计算能力

3.       深度学习中的CPU+GPU集群架构

        CPU+GPU集群工作模式(图3),每个节点内采用CPU+GPU异构模式,并且每个节点可以配置多块GPU卡。节点间采用高速InfiniBand网络互连,速度可以达到双向56Gb/s,实测双向5GB/s。后端采用并行文件系统。采用数据划分、任务划分的方式对应用进行并行化,适用于大规模数据并行计算。

图3 CPU+GPU集群架构

4.       利用GPU加速深度学习算法


4.1.       单GPU并行

图4 单GPU计算流程

        针对每次训练数据,模型内计算通过多次GPU 内核的调用完成计算。权重W值一直存在GPU内存中,直到所有训练数据计算完毕之后回传到系统内存中。Data为图像或语音数据。

4.2.       多GPU卡并行

       多GPU并行计算时,各GPU有自己独立的内存,卡之间的并行属于分布式计算模式。针对深度学习算法,采用多GPU卡计算可以采用两种并行方法:数据并行和模型并行。

4.2.1.       数据并行

       数据并行是指不同的GPU计算不同的训练数据,即把训练数据划分给不同的GPU进行分别计算,由于训练是逐步训练的,后一个训练数据的计算需要前一个训练数据更新的W,数据并行改变了这个计算顺序,多GPU计算需要进行W的互相通信,满足训练的特点,使训练可以收敛。

       数据并行如图5所示,多GPU训练不同的数据,每训练一次需要同步W,使得后面的训练始终为最新的W。

图5 数据并行

数据并行的特点:

1)        优点

            a)        实现比较容易,也比较容易扩展

            b)        只需要进行W的通信,模型内的数据不需要通信

2)        缺点

           a)        当模型较大时,GPU内存无法满足存储要求,无法完成计算

        根据多GPU卡之间的W通信,下面介绍两种通信方法:主从模式和令牌环模式。

1)        主从模式

       主从模式:选择一个进程或线程作为主进程或线程,各个GPU把每次训练得到的ΔW发给主进程或线程,主进程或线程进行W更新,然后再发送给GPU,GPU再进行下一个数据的训练。如图6所示。

图6 主从模式

2)        令牌环模式

       令牌环模式:每个GPU把自己训练得到的ΔW更新到W上,并且发送到下一个GPU,保证令牌环上的W始终为最新的W。如图7所示。

图7 令牌环模式

两种模式对比如表1

表1 主从模式和令牌环模式对比

模式

优点

缺点

主从模式

收敛速度更快

GPU计算需要等待,影响GPU计算;主进程或线程压力较大

令牌环模式

GPU计算不需要等待通信,性能更好

通信速度影响收敛的速度

4.2.2.       模型并行

        模型并行是指多个GPU同时计算同一个训练数据,多个GPU对模型内的数据进行划分,如图8所示。Kernel计算和通信流程如图9所示,在一次训练数据多层计算过程中,每个GPU内核计算之后需要互相交换数据才能进行下一次的计算。

图8 模型并行

图9 模型并行:多GPU计算内核和通信示意图

模型并行特点:

1)        优点

           a)        可以处理大模型的情况

2)        缺点

           a)        需要更频繁的通信,增加通信压力

           b)        实现难度较大

4.3.       GPU集群并行

          GPU集群并行模式即为多GPU并行中各种并行模式的扩展,如表2所示。节点间采用InfiniBand通信,节点间的GPU通过RMDA通信,节点内多GPU之间采用P2P通信。

表2 GPU集群并行模式

模式

节点间

节点内

特点

模式1

令牌环

单一模式的缺点放大

模式2

主从

模式3

模型并行

模式4

令牌环

主从

结合各种模式的有点,避免某一模式的缺点放大

模式5

主从

令牌环

模式6

令牌环

模型并行

模式7

主从

模型并行

4.4.       性能分享

4.4.1.       基于GPU集群的Caffe并行加速

图10 Caffe性能

8节点GPU服务器,2 K20mGPU/节点,56Gb/s InfiniBand网络,Lustre并行文件系统

4.4.2.       基于GPU集群的DNN并行加速

图11 DNN测试性能

4节点GPU服务器,4 K20mGPU/节点,56Gb/s InfiniBand网络

5.       CPU+FPGA协同计算加速线上计算

        相对于训练计算,线上识别的计算是小而众多的任务计算,每次请求的计算比较小,但请求的任务数十分庞大,GPU计算虽然获得很好的性能,但功耗仍然是个严峻的问题。

        目前主流的FPGA卡功耗只有主流GPU的十分之一,性能相差2-3倍,FPGA相对于GPU具有更高的GFlops/W。

利用FPGA解决线上识别计算可以采用分布式+FPGA计算的模式,如图12所示,上层可以采用Hadoop或Spark调度,底层利用FPGA进行计算。

图12 分布式计算+FPGA计算

        目前,FPGA已开始支持高级语言,如AlteraFPGA支持OpenCL,Xilinx FPGA支持HLS,这对程序员利用FPGA开发减低了难度。这些新平台的支持还有很多问题,也许后面会支持的越来越好。

 

备注:由于对深度学习算法了解比较肤浅,以上内容难免无误,请大家理解并提出修改意见。

 QQ:331526010

Email:zhang03_11@163.com

 

 

 

2017-06-22 22:46:36 u014380165 阅读数 1832
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2861 人正在学习 去看看 王而川

本篇博文主要介绍深度学习算法的一些经验,主要参考Andrew NG的新书《Machine Learning Yearning》,目前出到第14章,基本上都是介绍深度学习在工程上的应用,全书没有数学公式,可以说是干货满满,非常值得一读!接下来我将结合自己的项目经历,以这本书为顺序介绍自己的心得体会。

链接(1~12章):
https://gallery.mailchimp.com/dc3a7ef4d750c0abfc19202a3/files/Machine_Learning_Yearning_V0.5_01.pdf
链接(第13章):
https://gallery.mailchimp.com/dc3a7ef4d750c0abfc19202a3/files/Machine_Learning_Yearning_V0.5_02.pdf
链接(第14章):
https://gallery.mailchimp.com/dc3a7ef4d750c0abfc19202a3/files/Machine_Learning_Yearning_V0.5_03.pdf

一、Why Machine Learning Strategy
这一章主要是抛砖引玉,指出在你的深度学习模型遇到问题的时候,你需要选择合适的方法解决,那么一般都有哪些方法呢?作者列举了以下几个:
1、获取更多的数据。
2、增加训练样本的多样性。
3、增加迭代次数。
4、试试更深、更宽的网络,比如增加层数,卷积核个数,参数等等。
5、试试更小的网络。
6、加正则项,比如L2正则项。
7、改变你的网络结构,比如激活方式,卷积核个数等。

个人感悟增加训练样本的多样性可以这么理解:假如你要做猫狗分类,那么不同种类、不同姿势、睡觉的吃饭的等等的猫,各种各样都来一些,对提升你的算法效果是有帮助的。是否要增加迭代次数可以根据你的loss情况进行判断,当你的loss还没趋于平稳的时候,而且模型不太过拟合时,可以增加迭代次数。经验而言需要把你的全部数据跑几十遍才能达到不错的效果。更深的网络可以通过增加层数达到,比如像ResNet-152,当然原本简单增加层数的时候会遇到梯度衰减严重难以训练的情况,所以有了ResNet网络来解决这个问题。更宽的网络主要是通过增加某些层的卷积核的个数,一个卷积核相当于提取了一种特征,卷积核越多,特征越丰富,当然也增加了计算量。正则项一般是在过拟合的时候使用,简单讲就是限制权值的大小,L2是将权值的平方和加入到目标函数中,最后会使得权值趋于平滑,还有一种正则项是L1,可以使得权值趋于稀疏,即许多项为0。改变网络结构一般是比较细的调整,比如激活从ReLU改为pReLU,某层卷积核的大小的改变等等,一般小改的效果不会太明显。

二、How to use this book to help your team
这一章基本上没讲什么东西,略过。

三、Prerequisites and Notation
这一章也没什么重要内容,就是说如果你对机器学习不是很了解,可以看看这个链接:http://ml-class.org

四、Scale drives machine learning progress
其实深度学习(或者叫神经网络)在几十年前就有了,但是为什么现在才开始这么火?作者提到两个主要因素:
1、足够的数据
2、足够的计算能力
虽然现在数据有很多,但是传统的机器学习算法,比如逻辑回归,随着数据量的增加,其效果会遇到明显的瓶颈,此时如果采用不同深度的神经网络来训练,效果基本随着网络深度的增加而增加。如下图:

这里写图片描述

为什么会这样?因为在小数据上,可以人工构造特征,一般而言在小数据集上构造的特征还是十分有效的,但是随着数据集的增加,人工构造特征会愈加困难。

现在,对于深度学习模型,最常用的提高算法表现能力的方式就是两种:用更大的网络和用更多的数据。

个人感悟:非常同意最后这句话,也是我在工程项目中模型调优的方向,一般而言,增加或调整你的数据以及修改你的网络结构对你最后的效果提升是非常明显的。至于调参,应该要放在最后一步,一方面因为调参非常耗费时间且需要经验和运气;另一方面因为只要几个重要的超参数(学习率,mini-batch size)的量级没有设置得太过离谱,一般而言模型都能取得不错的效果,而且调参的提升空间不会太大。

五、Your development and test sets
一般而言,在开展深度学习项目的时候,都会将数据分成三部分:训练集,验证集,测试集。你的模型在训练集上训练,然后用验证集来验证其效果,根据验证集的结果进行模型优化。作者强调你的测试集一定要和真实的数据有相同分布。

个人感悟:有些人可能觉得直接分成训练集和测试集就行了,为什么还要加一个验证集。其实应该这么理解,验证集也是一个测试集,用来测试你的模型的泛化能力。而测试集一般是指线上的环境。一般而言我们拿到数据,可以分成训练集和验证集,要随机分,这样训练集和验证集才能有相似的分布,然后就在这两个数据集上不断训练和优化我们的模型。最后将模型应用到实际场景中,这实际场景其实就是我们的测试集,因为实际场景中数据一般会比我们之前收集的数据更多样,所以模型表现不如线下验证集是正常的,因为你一开始拿到的数据不可能十全十美,这时需要将这些数据再加到我们的训练集和验证集中,再训练和优化,直到迭代到下一个版本。如此不断重复。总之记住:训练集,验证集,测试集要尽可能具有相同分布。

六、Your dev and test sets should come from the same distribution
跟第五章类似,强调验证集和测试集要有相同的分布,否则你可能在验证集上训练出一个非常好的模型,但是在测试集上表现非常差。

七、How large do the dev/test sets need to be?
这一章主要讲验证集和测试集需要多大比较合适?如果你的验证集只要100个样本,那么你的准确率提高的最小单位是1%,而不可能是0.1%,除非你的验证集增加到1000个样本。测试集样本也需要大到能足够表达你的模型效果才行,但是一般也不建议太大。

个人感悟:我觉得对于验证集和测试集的划分没有硬性规定,一般我将数据集分成训练:验证=9:1。

八、Establish a single-number evalution metric for your team to optimize
主要是讲模型的评价标准。最好能用一个评价标准(比如准确率)来判断模型优劣,而不是用多个标准(比如precision和recall)。主要是因为多个标准不好比较算法的效果。比如这个图:

这里写图片描述

其实如果要兼顾precision和recall,可以采用F1 score。

九、Optimizing and satisficing metrics
在权衡算法效果和速度的时候,除了可以用类似Accuracy-0.5*RunningTime的方式来比较,还可以采用其他方式,比如:假如可以接受的运行时间是100ms,那么就在这个限制条件下寻找准确率最高的算法。当然,如果你有多个限制条件,比如模型大小,运行时间,算法效果等,那可以在挨个满足条件的前提下找到最好的。还有一个例子是false positive rate和false negative rate,比如你希望在false positive rate为0的前提下降低你的false negative rate。

十、Having a dev set and metric speeds up iterations
当你拿到一个问题的时候,你要思考这个问题要用什么样的方式解决,然后把这个方式用代码表达出来,最后根据实验结果去思考之前的解决方式是否还有改进的地方,不断迭代。作者给出的这个图非常形象

这里写图片描述

十一、When to change dev/test sets and metrics
作者提到在开始一个项目的时候,最好在一周内就能定义出验证集和测试集以及评价标准,而不是花太长的时间去制定和思考。后期当你发现你之前定义的验证集和测试集存在缺陷的时候,就应该尽快修改。这里有三个需要注意的点,如果你有这三种情况,那么就需要修改你的验证集了。
1、实际的数据分布和你验证集的数据分布不同。
2、在验证集上过拟合了。
3、你的评价标准和模型的优化方向不一致。比如你的一个图像分类算法,模型A的准确率比模型B的准确要高,但是有时候模型A容易漏判一些特殊图像,这是不能容忍的,而模型B不会,因此准确讲模型B的效果要比模型A要好。怎么改进呢?可以通过对漏判一些特殊图像做惩罚,而不仅仅用准确率来表征模型优劣。

十二、Takeaways: Setting up development and test sets
1、你的验证集和测试集要尽可能从你实际应用场景的数据中获取。验证集和测试集不一定要跟你的训练数据有相同分布。(这点我认为最好还是训练集和验证集有相似的分布,如果训练数据和验证数据分布太大,你可能训练多次都难以得到好的效果,)

未完,待补充

没有更多推荐了,返回首页