Category Archives: ML&DL

一个框架解决几乎所有机器学习问题

周一个叫 Abhishek Thakur 的数据科学家,在他的 Linkedin 发表了一篇文章 Approaching (Almost) Any Machine Learning Problem,介绍他建立的一个自动的机器学习框架,几乎可以解决任何机器学习问题,项目很快也会发布出来。这篇文章迅速火遍 Kaggle,他参加过100多个数据科学相关的竞赛,积累了很多宝贵的经验,看他很幽默地说“写这样的框架需要很多丰富的经验,不是每个人都有这样的经历,而很多人有宝贵的经验,但是他们不愿意分享,我呢恰好是又有一些经验,又愿意分享的人”。当然这篇文章也是受到争议的,很多人觉得并不全面。

我最近也在准备参加 Kaggle,之前看过几个例子,自己也总结了一个分析的流程,今天看了这篇文章,里面提到了一些高效的方法,最干货的是,他做了一个表格,列出了各个算法通常需要训练的参数。

这个问题很重要,因为大部分时间都是通过调节参数,训练模型来提高精度。作为一个初学者,第一阶段,最想知道的问题,就是如何调节参数。因为分析的套路很简单,就那么几步,常用的算法也就那么几个,以为把算法调用一下就可以了么,那是肯定不行的。实际过程中,调用完算法后,结果一般都不怎么好,这个时候还需要进一步分析,哪些参数可以调优,哪些数据需要进一步处理,还有什么更合适的算法等等问题。

接下来一起来看一下他的框架。

据说数据科学家 60-70% 的时间都花在数据清洗和应用模型算法上面,这个框架主要针对算法的应用部分。

1507706111793_5442_1507706107871

Pipeline

什么是 Kaggle?

Kaggle是一个数据科学竞赛的平台,很多公司会发布一些接近真实业务的问题,吸引爱好数据科学的人来一起解决,可以通过这些数据积累经验,提高机器学习的水平。

应用算法解决 Kaggle 问题,一般有以下几个步骤:

  • 第一步:识别问题
  • 第二步:分离数据
  • 第三步:构造提取特征
  • 第四步:组合数据
  • 第五步:分解
  • 第六步:选择特征
  • 第七步:选择算法进行训练

当然,工欲善其事,必先利其器,要先把工具和包都安好。
最方便的就是安装 Anaconda,这里面包含大部分数据科学所需要的包,直接引入就可以了,常用的包有:

  • pandas:常用来将数据转化成 dataframe 形式进行操作
  • scikit-learn:里面有要用到的机器学习算法模型
  • matplotlib:用来画图
  • 以及 xgboost,keras,tqdm 等。

第一步:识别问题

在这一步先明确这个问题是分类还是回归。通过问题和数据就可以判断出来,数据由 X 和 label 列构成,label 可以一列也可以多列,可以是二进制也可以是实数,当它为二进制时,问题属于分类,当它为实数时,问题属于回归。

第二步:分离数据

1507706161329_2449_1507706157270

为什么需要将数据分成两部分?

用 Training Data 来训练模型,用 Validation Data 来检验这个模型的表现,不然的话,通过各种调节参数,模型可以在训练数据集上面表现的非常出色,但是这可能会是过拟合,过拟合就是太依赖现有的数据了,拟合的效果特别好,但是只适用于训练集,以致于来一个新的数据,就不知道该预测成什么了。所以需要有 Validation 来验证一下,看这个模型是在那里自娱自乐呢,还是真的表现出色。

在 scikit learn 包里就有工具可以帮你做到这些:
分类问题用 StrtifiedKFold

from sklearn.cross_validation import StratifiedKFold

回归问题用 KFold

from sklearn.cross_validation import KFold

第三步:构造特征

这个时候,需要将数据转化成模型需要的形式。数据有三种类型:数字,类别,文字。当数据是类别的形式时,需要将它的每一类提取出来作为单独一列,然后用二进制表示每条记录相应的值。例如:

record 1: 性别 女
record 2:性别 女
record 3:性别 男

转化之后就是:

         女 男
record 1: 1 0
record 2:1 0
record 3:0 1

这个过程 sklearn 也可以帮你做到:

from sklearn.preprocessing import LabelEncoder

或者

from sklearn.preprocessing import OneHotEncoder

第四步:组合数据

处理完 Feature 之后,就将它们组合到一起。
如果数据是稠密的,就可以用 numpy 的 hstack:

import numpy as np
X = np.hstack((x1, x2, ...))

如果是稀疏的,就用 sparse 的 hstack:

from scipy import sparse
X = sparse.hstack((x1, x2, ...))

组合之后,就可以应用以下算法模型:

  • RandomForestClassifier
  • RandomForestRegressor
  • ExtraTreesClassifier
  • ExtraTreesRegressor
  • XGBClassifier
  • XGBRegressor

但是不能应用线性模型,线性模型之前需要对数据进行正则化而不是上述预处理。

第五步:分解

这一步是为了进一步优化模型,可以用以下方法:

1507706259451_2054_1507706255470

PCA:Principal components analysis,主成分分析,是一种分析、简化数据集的技术。用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征。

from sklearn.decomposition import PCA

对于文字数据,在转化成稀疏矩阵之后,可以用 SVD

from sklearn.decomposition import TruncatedSVD

SVD:Singular Value Decomposition,奇异值分解,是线性代数中一种重要的矩阵分解,它总能找到标准化正交基后方差最大的维度,因此用它进行降维去噪。

第六步:选择特征

当特征个数越多时,分析特征、训练模型所需的时间就越长,容易引起“维度灾难”,模型也会越复杂,推广能力也会下降,所以需要剔除不相关或亢余的特征。

常用的算法有完全搜索,启发式搜索,和随机算法。

例如,Random Forest:

from sklearn.ensemble import RandomForestClassifier

或者 xgboost:

import xgboost as xgb

对于稀疏的数据,一个比较有名的方法是 chi-2:

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

第七步:选择算法进行训练

选择完最相关的参数之后,接下来就可以应用算法,常用的算法有:

Classification:
Random Forest
GBM
Logistic Regression
Naive Bayes
Support Vector Machines
k-Nearest Neighbors

Regression
Random Forest
GBM
Linear Regression
Ridge
Lasso
SVR

scikit-learn里可以看到分类和回归的可用的算法一览,包括它们的原理和例子代码。

在应用各算法之前先要明确这个方法到底是否合适。
为什么那么多算法里,只提出这几个算法呢,这就需要对比不同算法的性能了。
这篇神文 Do we Need Hundreds of Classifiers to Solve Real World Classification Problems 测试了179种分类模型在UCI所有的121个数据上的性能,发现Random Forests 和 SVM 性能最好。
我们可以学习一下里面的调研思路,看看是怎么样得到比较结果的,在我们的实践中也有一定的指导作用。

1507706339459_6332_1507706335760各算法比较

但是直接应用算法后,一般精度都不是很理想,这个时候需要调节参数,最干货的问题来了,什么模型需要调节什么参数呢?

1507706352167_4129_1507706348227

虽然在sklearn的文档里,会列出所有算法所带有的参数,但是里面并不会说调节哪个会有效。在一些mooc课程里,有一些项目的代码,里面可以看到一些算法应用时,他们重点调节的参数,但是有的也不会说清楚为什么不调节别的。这里作者根据他100多次比赛的经验,列出了这个表,我觉得可以借鉴一下,当然,如果有时间的话,去对照文档里的参数列表,再查一下算法的原理,通过理论也是可以判断出来哪个参数影响比较大的。

调参之后,也并不就是大功告成,这个时候还是需要去思考,是什么原因造成精度低的,是哪些数据的深意还没有被挖掘到,这个时候需要用统计和可视化去再一次探索数据,之后就再走一遍上面的过程。

我觉得这里还提到了很有用的一条经验是,把所有的 transformer 都保存起来,方便在 validation 数据集上面应用:

1507706374144_6119_1507706370146

文章里介绍了分析问题的思路,还提到了几条很实用的经验,不过经验终究是别人的经验,只能借鉴,要想提高自己的水平,还是要看到作者背后的事情,就是参加了100多次实战,接下来就去行动吧,享受用算法和代码与数据玩耍的兴奋吧。

from:https://cloud.tencent.com/community/article/440346

Data science Python notebooks

 

data-science-ipython-notebooks

Index

 

deep-learning

IPython Notebook(s) demonstrating deep learning functionality.

 

tensor-flow-tutorials

Additional TensorFlow tutorials:

Notebook Description
tsf-basics Learn basic operations in TensorFlow, a library for various kinds of perceptual and language understanding tasks from Google.
tsf-linear Implement linear regression in TensorFlow.
tsf-logistic Implement logistic regression in TensorFlow.
tsf-nn Implement nearest neighboars in TensorFlow.
tsf-alex Implement AlexNet in TensorFlow.
tsf-cnn Implement convolutional neural networks in TensorFlow.
tsf-mlp Implement multilayer perceptrons in TensorFlow.
tsf-rnn Implement recurrent neural networks in TensorFlow.
tsf-gpu Learn about basic multi-GPU computation in TensorFlow.
tsf-gviz Learn about graph visualization in TensorFlow.
tsf-lviz Learn about loss visualization in TensorFlow.

tensor-flow-exercises

Notebook Description
tsf-not-mnist Learn simple data curation by creating a pickle with formatted datasets for training, development and testing in TensorFlow.
tsf-fully-connected Progressively train deeper and more accurate models using logistic regression and neural networks in TensorFlow.
tsf-regularization Explore regularization techniques by training fully connected networks to classify notMNIST characters in TensorFlow.
tsf-convolutions Create convolutional neural networks in TensorFlow.
tsf-word2vec Train a skip-gram model over Text8 data in TensorFlow.
tsf-lstm Train a LSTM character model over Text8 data in TensorFlow.

 

theano-tutorials

Notebook Description
theano-intro Intro to Theano, which allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. It can use GPUs and perform efficient symbolic differentiation.
theano-scan Learn scans, a mechanism to perform loops in a Theano graph.
theano-logistic Implement logistic regression in Theano.
theano-rnn Implement recurrent neural networks in Theano.
theano-mlp Implement multilayer perceptrons in Theano.

 

keras-tutorials

Notebook Description
keras Keras is an open source neural network library written in Python. It is capable of running on top of either Tensorflow or Theano.
setup Learn about the tutorial goals and how to set up your Keras environment.
intro-deep-learning-ann Get an intro to deep learning with Keras and Artificial Neural Networks (ANN).
theano Learn about Theano by working with weights matrices and gradients.
keras-otto Learn about Keras by looking at the Kaggle Otto challenge.
ann-mnist Review a simple implementation of ANN for MNIST using Keras.
conv-nets Learn about Convolutional Neural Networks (CNNs) with Keras.
conv-net-1 Recognize handwritten digits from MNIST using Keras – Part 1.
conv-net-2 Recognize handwritten digits from MNIST using Keras – Part 2.
keras-models Use pre-trained models such as VGG16, VGG19, ResNet50, and Inception v3 with Keras.
auto-encoders Learn about Autoencoders with Keras.
rnn-lstm Learn about Recurrent Neural Networks (RNNs) with Keras.
lstm-sentence-gen Learn about RNNs using Long Short Term Memory (LSTM) networks with Keras.

deep-learning-misc

Notebook Description
deep-dream Caffe-based computer vision program which uses a convolutional neural network to find and enhance patterns in images.

 

scikit-learn

IPython Notebook(s) demonstrating scikit-learn functionality.

Notebook Description
intro Intro notebook to scikit-learn. Scikit-learn adds Python support for large, multi-dimensional arrays and matrices, along with a large library of high-level mathematical functions to operate on these arrays.
knn Implement k-nearest neighbors in scikit-learn.
linear-reg Implement linear regression in scikit-learn.
svm Implement support vector machine classifiers with and without kernels in scikit-learn.
random-forest Implement random forest classifiers and regressors in scikit-learn.
k-means Implement k-means clustering in scikit-learn.
pca Implement principal component analysis in scikit-learn.
gmm Implement Gaussian mixture models in scikit-learn.
validation Implement validation and model selection in scikit-learn.

 

statistical-inference-scipy

IPython Notebook(s) demonstrating statistical inference with SciPy functionality.

Notebook Description
scipy SciPy is a collection of mathematical algorithms and convenience functions built on the Numpy extension of Python. It adds significant power to the interactive Python session by providing the user with high-level commands and classes for manipulating and visualizing data.
effect-size Explore statistics that quantify effect size by analyzing the difference in height between men and women. Uses data from the Behavioral Risk Factor Surveillance System (BRFSS) to estimate the mean and standard deviation of height for adult women and men in the United States.
sampling Explore random sampling by analyzing the average weight of men and women in the United States using BRFSS data.
hypothesis Explore hypothesis testing by analyzing the difference of first-born babies compared with others.

 

pandas

IPython Notebook(s) demonstrating pandas functionality.

Notebook Description
pandas Software library written for data manipulation and analysis in Python. Offers data structures and operations for manipulating numerical tables and time series.
github-data-wrangling Learn how to load, clean, merge, and feature engineer by analyzing GitHub data from the Viz repo.
Introduction-to-Pandas Introduction to Pandas.
Introducing-Pandas-Objects Learn about Pandas objects.
Data Indexing and Selection Learn about data indexing and selection in Pandas.
Operations-in-Pandas Learn about operating on data in Pandas.
Missing-Values Learn about handling missing data in Pandas.
Hierarchical-Indexing Learn about hierarchical indexing in Pandas.
Concat-And-Append Learn about combining datasets: concat and append in Pandas.
Merge-and-Join Learn about combining datasets: merge and join in Pandas.
Aggregation-and-Grouping Learn about aggregation and grouping in Pandas.
Pivot-Tables Learn about pivot tables in Pandas.
Working-With-Strings Learn about vectorized string operations in Pandas.
Working-with-Time-Series Learn about working with time series in pandas.
Performance-Eval-and-Query Learn about high-performance Pandas: eval() and query() in Pandas.

 

matplotlib

IPython Notebook(s) demonstrating matplotlib functionality.

Notebook Description
matplotlib Python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms.
matplotlib-applied Apply matplotlib visualizations to Kaggle competitions for exploratory data analysis. Learn how to create bar plots, histograms, subplot2grid, normalized plots, scatter plots, subplots, and kernel density estimation plots.
Introduction-To-Matplotlib Introduction to Matplotlib.
Simple-Line-Plots Learn about simple line plots in Matplotlib.
Simple-Scatter-Plots Learn about simple scatter plots in Matplotlib.
Errorbars.ipynb Learn about visualizing errors in Matplotlib.
Density-and-Contour-Plots Learn about density and contour plots in Matplotlib.
Histograms-and-Binnings Learn about histograms, binnings, and density in Matplotlib.
Customizing-Legends Learn about customizing plot legends in Matplotlib.
Customizing-Colorbars Learn about customizing colorbars in Matplotlib.
Multiple-Subplots Learn about multiple subplots in Matplotlib.
Text-and-Annotation Learn about text and annotation in Matplotlib.
Customizing-Ticks Learn about customizing ticks in Matplotlib.
Settings-and-Stylesheets Learn about customizing Matplotlib: configurations and stylesheets.
Three-Dimensional-Plotting Learn about three-dimensional plotting in Matplotlib.
Geographic-Data-With-Basemap Learn about geographic data with basemap in Matplotlib.
Visualization-With-Seaborn Learn about visualization with Seaborn.

 

numpy

IPython Notebook(s) demonstrating NumPy functionality.

Notebook Description
numpy Adds Python support for large, multi-dimensional arrays and matrices, along with a large library of high-level mathematical functions to operate on these arrays.
Introduction-to-NumPy Introduction to NumPy.
Understanding-Data-Types Learn about data types in Python.
The-Basics-Of-NumPy-Arrays Learn about the basics of NumPy arrays.
Computation-on-arrays-ufuncs Learn about computations on NumPy arrays: universal functions.
Computation-on-arrays-aggregates Learn about aggregations: min, max, and everything in between in NumPy.
Computation-on-arrays-broadcasting Learn about computation on arrays: broadcasting in NumPy.
Boolean-Arrays-and-Masks Learn about comparisons, masks, and boolean logic in NumPy.
Fancy-Indexing Learn about fancy indexing in NumPy.
Sorting Learn about sorting arrays in NumPy.
Structured-Data-NumPy Learn about structured data: NumPy’s structured arrays.

 

python-data

IPython Notebook(s) demonstrating Python functionality geared towards data analysis.

Notebook Description
data structures Learn Python basics with tuples, lists, dicts, sets.
data structure utilities Learn Python operations such as slice, range, xrange, bisect, sort, sorted, reversed, enumerate, zip, list comprehensions.
functions Learn about more advanced Python features: Functions as objects, lambda functions, closures, *args, **kwargs currying, generators, generator expressions, itertools.
datetime Learn how to work with Python dates and times: datetime, strftime, strptime, timedelta.
logging Learn about Python logging with RotatingFileHandler and TimedRotatingFileHandler.
pdb Learn how to debug in Python with the interactive source code debugger.
unit tests Learn how to test in Python with Nose unit tests.

 

kaggle-and-business-analyses

IPython Notebook(s) used in kaggle competitions and business analyses.

Notebook Description
titanic Predict survival on the Titanic. Learn data cleaning, exploratory data analysis, and machine learning.
churn-analysis Predict customer churn. Exercise logistic regression, gradient boosting classifers, support vector machines, random forests, and k-nearest-neighbors. Includes discussions of confusion matrices, ROC plots, feature importances, prediction probabilities, and calibration/descrimination.

 

spark

IPython Notebook(s) demonstrating spark and HDFS functionality.

Notebook Description
spark In-memory cluster computing framework, up to 100 times faster for certain applications and is well suited for machine learning algorithms.
hdfs Reliably stores very large files across machines in a large cluster.

 

mapreduce-python

IPython Notebook(s) demonstrating Hadoop MapReduce with mrjob functionality.

Notebook Description
mapreduce-python Runs MapReduce jobs in Python, executing jobs locally or on Hadoop clusters. Demonstrates Hadoop Streaming in Python code with unit test and mrjob config file to analyze Amazon S3 bucket logs on Elastic MapReduce. Disco is another python-based alternative.

 

aws

IPython Notebook(s) demonstrating Amazon Web Services (AWS) and AWS tools functionality.

Also check out:

  • SAWS: A Supercharged AWS command line interface (CLI).
  • Awesome AWS: A curated list of libraries, open source repos, guides, blogs, and other resources.
Notebook Description
boto Official AWS SDK for Python.
s3cmd Interacts with S3 through the command line.
s3distcp Combines smaller files and aggregates them together by taking in a pattern and target file. S3DistCp can also be used to transfer large volumes of data from S3 to your Hadoop cluster.
s3-parallel-put Uploads multiple files to S3 in parallel.
redshift Acts as a fast data warehouse built on top of technology from massive parallel processing (MPP).
kinesis Streams data in real time with the ability to process thousands of data streams per second.
lambda Runs code in response to events, automatically managing compute resources.

 

commands

IPython Notebook(s) demonstrating various command lines for Linux, Git, etc.

Notebook Description
linux Unix-like and mostly POSIX-compliant computer operating system. Disk usage, splitting files, grep, sed, curl, viewing running processes, terminal syntax highlighting, and Vim.
anaconda Distribution of the Python programming language for large-scale data processing, predictive analytics, and scientific computing, that aims to simplify package management and deployment.
ipython notebook Web-based interactive computational environment where you can combine code execution, text, mathematics, plots and rich media into a single document.
git Distributed revision control system with an emphasis on speed, data integrity, and support for distributed, non-linear workflows.
ruby Used to interact with the AWS command line and for Jekyll, a blog framework that can be hosted on GitHub Pages.
jekyll Simple, blog-aware, static site generator for personal, project, or organization sites. Renders Markdown or Textile and Liquid templates, and produces a complete, static website ready to be served by Apache HTTP Server, Nginx or another web server.
pelican Python-based alternative to Jekyll.
django High-level Python Web framework that encourages rapid development and clean, pragmatic design. It can be useful to share reports/analyses and for blogging. Lighter-weight alternatives include Pyramid, Flask, Tornado, and Bottle.

misc

IPython Notebook(s) demonstrating miscellaneous functionality.

Notebook Description
regex Regular expression cheat sheet useful in data wrangling.
algorithmia Algorithmia is a marketplace for algorithms. This notebook showcases 4 different algorithms: Face Detection, Content Summarizer, Latent Dirichlet Allocation and Optical Character Recognition.

notebook-installation

anaconda

Anaconda is a free distribution of the Python programming language for large-scale data processing, predictive analytics, and scientific computing that aims to simplify package management and deployment.

Follow instructions to install Anaconda or the more lightweight miniconda.

dev-setup

For detailed instructions, scripts, and tools to set up your development environment for data analysis, check out the dev-setup repo.

running-notebooks

To view interactive content or to modify elements within the IPython notebooks, you must first clone or download the repository then run the notebook. More information on IPython Notebooks can be found here.

$ git clone https://github.com/donnemartin/data-science-ipython-notebooks.git
$ cd data-science-ipython-notebooks
$ jupyter notebook

Notebooks tested with Python 2.7.x.

credits

contributing

Contributions are welcome! For bug reports or requests please submit an issue.

contact-info

Feel free to contact me to discuss any issues, questions, or comments.

license

This repository contains a variety of content; some developed by Donne Martin, and some from third-parties. The third-party content is distributed under the license provided by those parties.

The content developed by Donne Martin is distributed under the following license:

I am providing code and resources in this repository to you under an open source license. Because this is my personal repository, the license you receive to my code and resources is from me and not my employer (Facebook).

Copyright 2015 Donne Martin

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License

使用Keras卷积神经网络

这篇文章记录如何用 Keras 实现 卷积神经网络 CNN,并训练模型用于图片分类;以及 CNN 中一些超参的调整和自己的理解。

数据集

http://www.ivl.disco.unimib.it/activities/large-age-gap-face-verification/

这个图片数据集是一些名人的少年时和成年后的对比照片,格式为 100*100,RGB。

将图片分成成年和少年两个类别,实现的分类器是个二分器,训练出来的模型能够对输入的照片进行分类,给出一个 old 或者 young 的 label。

整理数据集为如下目录结构:

train  
├── old
│   ├── 1200 张图片
├── young
│   ├── 1200 张图片

validation  
├── old
│   ├── 600 张图片
├── young
│   ├── 600 张图片

test  
├── old
│   ├── 110 张图片
├── young
│   ├── 110 张图片

train 为训练组,validation 为验证组,训练时使用交叉验证,train 和 validation 的数据都会使用。

test 为验证模型的测试组。

图片展示

以下是 train/old 组展示的部分图片:

%matplotlib inline

import os  
import matplotlib.pyplot as plt  
import matplotlib.image as mpimg

some_old_pics = os.listdir('train/old')  
show_rows = show_columns = 5  
for k in range(show_rows * show_rows):  
    image = mpimg.imread('train/old/%s' % some_old_pics[k])
    plt.subplot(show_rows, show_rows, k+1)
    plt.imshow(image)
    plt.axis('off')

“平均脸”

其实就是求每组图片的平均值,代码参考这里

import os, numpy, PIL  
from PIL import Image  
import matplotlib.pyplot as plt  
def plot_average_pic(group):  
    dirs = ["%s/%s" % (group, i) for i in ['old', 'young']]
    for k in range(len(dirs)):
        dir = dirs[k]
        imlist = ['%s/%s' % (dir, c) for c in os.listdir(dir)]
        w, h = Image.open(imlist[0]).size
        N = len(imlist)
        arr = numpy.zeros((h, w, 3), numpy.float)
        for im in imlist:
            imarr = numpy.array(Image.open(im), dtype=numpy.float)
            arr = arr + imarr / N
        arr = numpy.array(numpy.round(arr), dtype=numpy.uint8)
        image = Image.fromarray(arr, mode="RGB")
        plt.subplot(2, 3, k+1)
        plt.imshow(image)
        plt.title(dir)
        plt.axis('off')

结果如下:

好神奇 …

从“平均脸”这个结果来看,两组 label 确实有比较明显的区分。

创建 CNN 模型

导入的模块:

from keras.preprocessing.image import ImageDataGenerator  
from keras.models import Sequential  
from keras.layers import Conv2D, MaxPooling2D  
from keras.layers import Activation, Dropout, Flatten, Dense  

先定义好一些参数,所有图片的输入尺寸 (100*100,RGB 三通道),train / validation 样本数,训练轮次 epochs,以及小批量梯度下降训练样本值 batch_size:

img_width, img_height = 100, 100

train_data_dir = './train'  
validation_data_dir = './validation'  
nb_train_samples = 1200  
nb_validation_samples = 600  
epochs = 100  
batch_size = 16

input_shape = (img_width, img_height, 3)  

创建 CNN

model = Sequential()  
model.add(Conv2D(32, (3, 3), padding='same', input_shape=input_shape))  
model.add(Activation('relu'))  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32, (3, 3), padding='same'))  
model.add(Activation('relu'))  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64, (3, 3), padding='same'))  
model.add(Activation('relu'))  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())  
model.add(Dense(64))  
model.add(Activation('relu'))  
model.add(Dropout(0.5))

model.add(Dense(1))  
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',  
              optimizer='rmsprop',
              metrics=['accuracy'])

定义 train 和 validation 的 ImageDataGenerator,图像增强,用缩放、镜像、旋转等方式增加图片,以便扩大数据量:

train_datagen = ImageDataGenerator(  
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)
validation_datagen = ImageDataGenerator(  
    rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(  
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')
validation_generator = validation_datagen.flow_from_directory(  
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

开始训练:

from keras.callbacks import ModelCheckpoint, Callback, TensorBoard  
filepath="1.weights-improvement-{epoch:02d}-{val_acc:.2f}.h5"  
checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')  
tensorboard = TensorBoard(log_dir='logs', histogram_freq=0)  
callbacks_list = [checkpoint, tensorboard]

model.fit_generator(  
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size,
    callbacks=callbacks_list)

可以看到前几次训练之后验证组的准确率 ( val_acc ) 就可以达到 82% 左右了。

( 一个 epoch 用 i7 CPU 需要 180s,而 GTX1080 GPU 只需要 3s )

100 轮训练后成绩最好的结果:

loss: 0.2957 - acc: 0.8875 - val_loss: 0.2994 - val_acc: 0.9139  

val_acc 比 acc 还要高 …

Tenserboard 上看到的训练过程:

验证模型:

导入效果最好的模型

from keras.models import load_model  
best_model = load_model('a.weights-improvement-64-0.91.h5')  

还是用 ImageDataGenerator:

datagen = ImageDataGenerator()  
test_generator = datagen.flow_from_directory(  
        './test',
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode='binary')

验证:

scores = best_model.evaluate_generator(  
        test_generator,
        val_samples=220)
print scores  

结果:

[2.7107817684386277, 0.82976878729858838]

准确率达到了 82.98%,效果还不错,但是距离训练时的 91.39% 还有一定的差距,比较明显的过拟合。

dropout

将模型中倒数第三层的 Dropout 参数,降低为 0.2,增加模型的泛化能力:

model.add(Dropout(0.2))  

训练及测试结果:

[train] loss: 0.2599 - acc: 0.9008 - val_loss: 0.2315 - val_acc: 0.9105
[test]  loss: 2.1801 - acc: 0.8636 

准确率提升至 86.36% 。

optimizer

将 optimizer 从 rmsprop 更改为当前比较流行的 adam:

model.compile(loss='binary_crossentropy',  
              optimizer='adam',
              metrics=['accuracy'])

结果:

[train] loss: 0.1916 - acc: 0.9250 - val_loss: 0.3205 - val_acc: 0.9037
[test]  loss: 1.4704 - acc: 0.8962

准确率进一步提升为 89.62% 。

从这次模型来看,测试结果与训练结果相当接近。

kernel size

将卷积层的卷积核大小从 (3,3) 改为 (5,5)

Conv2D(32, (5, 5), padding='same', input_shape=input_shape)  

可以理解为增加了神经网络的权重参数数量,因为卷积层的权重参数数量,以第一层卷积层为例:

3 * (3 * 3) * 32 + 32 = 896  

增大为:

3 * (5 * 5) * 32 + 32 = 2432  

( 乘式前面的 3 为卷积层的深度,第一层是输入层的深度;后面的 32 为过滤器的个数,加上的 32 为 bias 个数,每个过滤器 1 个 bias )

结果:

[train] loss: 0.1104 - acc: 0.9533 - val_loss: 0.3632 - val_acc: 0.9003
[test]  loss: 1.7149 - acc: 0.8902

可以看到训练时的训练组准确率达到了 95.33% 的较高水平,反映了权重参数数量增多的正面影响。

然而测试结果来看,与未改变卷积核大小时反而有些微下降,或许还应该降低 Dropout 的比例。

在此基础上将 Dropout 比例由 0.2 再次下降为 0.1,结果如下:

[train] loss: 0.1321 - acc: 0.9500 - val_loss: 0.3917 - val_acc: 0.8970
[test]  loss: 1.4034 - acc: 0.9124

测试的准确率超过了 91% !

padding

将卷积层中的 padding 参数改为默认的 valid,即:

Conv2D(32, (5, 5))  

保持 0.2 的 Dropout 比例

结果:

[train] loss: 0.1768 - acc: 0.9208 - val_loss: 0.3337 - val_acc: 0.8986
[test]  loss: 1.7612 - acc: 0.8902

从结果来看并没多大的区别。

activation

测试更换激活函数。比如使用 PReLU,Keras 里使用 PReLU 需要使用 advanced_activations 类,模型修改如下:

from keras.layers.advanced_activations import PReLU

model = Sequential()  
model.add(Conv2D(32, (5, 5), input_shape=input_shape, activation='linear'))  
model.add(PReLU())  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32, (5, 5), activation='linear'))  
model.add(PReLU())  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64, (5, 5), activation='linear'))  
model.add(PReLU())  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())  
model.add(Dense(64))  
model.add(Activation('relu'))  
model.add(Dropout(0.1))

model.add(Dense(1))  
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',  
              optimizer='adam',
              metrics=['accuracy'])

需要先声明一个 linear 激活函数的卷积层,然后再在后面增加一个 PReLU 层。

因为 PReLU 实际上会增加权重参数数量,因此使用了 0.1 的 Droupout。

结果:

[train] loss: 0.2656 - acc: 0.8850 - val_loss: 0.2623 - val_acc: 0.9054
[test]  loss: 1.9551 - acc: 0.8737

试下 LeakyReLU(alpha=0.001)

[train] loss: 0.2002 - acc: 0.9267 - val_loss: 0.2987 - val_acc: 0.8885

然而在加载最佳结果 load_model 时有报错,没有执行最佳模型的测试。在最后一组训练得出的 val_acc: 0.8497 结果的模型上测试结果如下:

[test]  loss: 2.1069 - acc: 0.8688

batch size

训练时的 batch size 对训练模型也有一定的影响,具体可参考知乎上的讨论

实际测试如下:( 在之前 91% 测试准确率模型基础上修改 batch_size )

单从这个测试结果上看,还是 batch size 为 16 的最佳。

对比 batch size = 16 的训练过程,batch size = 8 的 acc 开始时上升较快,val_acc 震荡更为明显:

deeper

更深的网络。

再增加一层卷积层,模型修改如下:

model = Sequential()  
model.add(Conv2D(32, (5, 5), padding='same', input_shape=input_shape))  
model.add(Activation('relu'))  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32, (5, 5), padding='same'))  
model.add(Activation('relu'))  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64, (5, 5), padding='same'))  
model.add(Activation('relu'))  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(128, (5, 5), padding='same'))  
model.add(Activation('relu'))  
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())  
model.add(Dense(128))  
model.add(Activation('relu'))  
model.add(Dropout(0.1))

model.add(Dense(1))  
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',  
              optimizer='adam',
              metrics=['accuracy'])

结果:

[train] loss: 0.2415 - acc: 0.9075 - val_loss: 0.3782 - val_acc: 0.8581
[test]  loss: 2.5879 - acc: 0.8361

可以看到过拟合严重了,或许对于数据量较少的训练集,使用更深的网络并不是一个较好的选择,比较容易出现过拟合。

最后

使用了测试结果为 91% 的模型,随便在谷歌上找了些图片进行测试,效果还不赖,如下图:

老年组 90% 准确率

温老四你怎么了 …

少年组 95% 准确率

詹老汉亮了。

参考

https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html

from:https://zhengheng.me/2017/08/30/keras-cnn/

NLP入门之语音模型原理

作者:云时之间

这一篇文章其实是参考了很多篇文章之后写出的一篇对于语言模型的一篇科普文,目的是希望大家可以对于语言模型有着更好地理解,从而在接下来的NLP学习中可以更顺利的学习.

1:传统的语音识别方法:

这里我们讲解一下是如何将声音变成文字,如果有兴趣的同学,我们可以深入的研究.

首先我们知道声音其实是一种波,常见的MP3等都是压缩的格式,必须要转化成非压缩的纯波形的文件来处理,下面以WAV的波形文件来示例:

大数据
在进行语音识别之前,有的需要把首尾段的静音进行切除,进行强制对齐,以此来降低对于后续步骤的干扰,整个静音的切除技术一般称为VAD,需要用到对于信号处理的一些技术.

如果要对于声音进行分析,就需要对于声音进行分帧,也就是把声音切成一小块一小块,每一小块称为一帧,分帧并不是简单地切开,而是使用的移动窗函数来实现的,并且帧和帧之间一般是有交叠的

大数据
就像上图这样

分帧之后,语音就变成了很多个小段,但是波形在时域上是没有什么描述能力的,因此就必须要将波形进行变换,常见的一种变换方法就是提取MFCC特征,然后根据人耳的生理特性,把每一帧波变成一个多维度向量,这个向量里是包含了这块语音的内容信息,这个过程叫做声学特征的提取,但是实际方法有很多,基本类似.

至此,声音就成了一个12行(假设声学特征是12维)、N列的一个矩阵,称之为观察序列,这里N为总帧数。观察序列如下图所示,图中,每一帧都用一个12维的向量表示,色块的颜色深浅表示向量值的大小。

大数据
接下来就要介绍怎样把这个矩阵变成文本了。首先要介绍两个概念:

1:音素:

单词的发音由音素构成。对英语,一种常用的音素集是卡内基梅隆大学的一套由39个音素构成的音素集,参见The CMU Pronouncing Dictionary‎。汉语一般直接用全部声母和韵母作为音素集,另外汉语识别还分有调无调,不详述。

1. 状态:这里理解成比音素更细致的语音单位就行啦。通常把一个音素划分成3个状态。

语音识别是怎么工作的呢?实际上一点都不神秘,无非是:

把帧识别成状态(难点)。

把状态组合成音素。

把音素组合成单词。

如下图所示:

大数据
图中,每个小竖条代表一帧,若干帧语音对应一个状态,每三个状态组合成一个音素,若干个音素组合成一个单词。也就是说,只要知道每帧语音对应哪个状态了,语音识别的结果也就出来了。

那每帧音素对应哪个状态呢?有个容易想到的办法,看某帧对应哪个状态的概率最大,那这帧就属于哪个状态。比如下面的示意图,这帧在状态S3上的条件概率最大,因此就猜这帧属于状态S3。

大数据
那这些用到的概率从哪里读取呢?有个叫“声学模型”的东西,里面存了一大堆参数,通过这些参数,就可以知道帧和状态对应的概率。获取这一大堆参数的方法叫做“训练”,需要使用巨大数量的语音数据,训练的方法比较繁琐,这里不讲。

但这样做有一个问题:每一帧都会得到一个状态号,最后整个语音就会得到一堆乱七八糟的状态号。假设语音有1000帧,每帧对应1个状态,每3个状态组合成一个音素,那么大概会组合成300个音素,但这段语音其实根本没有这么多音素。如果真这么做,得到的状态号可能根本无法组合成音素。实际上,相邻帧的状态应该大多数都是相同的才合理,因为每帧很短。

解决这个问题的常用方法就是使用隐马尔可夫模型(Hidden Markov Model,HMM)。这东西听起来好像很高深的样子,实际上用起来很简单: 第一步,构建一个状态网络。 第二步,从状态网络中寻找与声音最匹配的路径。

这样就把结果限制在预先设定的网络中,避免了刚才说到的问题,当然也带来一个局限,比如你设定的网络里只包含了“今天晴天”和“今天下雨”两个句子的状态路径,那么不管说些什么,识别出的结果必然是这两个句子中的一句。

那如果想识别任意文本呢?把这个网络搭得足够大,包含任意文本的路径就可以了。但这个网络越大,想要达到比较好的识别准确率就越难。所以要根据实际任务的需求,合理选择网络大小和结构。

搭建状态网络,是由单词级网络展开成音素网络,再展开成状态网络。语音识别过程其实就是在状态网络中搜索一条最佳路径,语音对应这条路径的概率最大,这称之为“解码”。路径搜索的算法是一种动态规划剪枝的算法,称之为Viterbi算法,用于寻找全局最优路径。

大数据
这里所说的累积概率,由三部分构成,分别是:

  1. 观察概率:每帧和每个状态对应的概率
  2. 转移概率:每个状态转移到自身或转移到下个状态的概率
  3. 语言概率:根据语言统计规律得到的概率

其中,前两种概率从声学模型中获取,最后一种概率从语言模型中获取。语言模型是使用大量的文本训练出来的,可以利用某门语言本身的统计规律来帮助提升识别正确率。语言模型很重要,如果不使用语言模型,当状态网络较大时,识别出的结果基本是一团乱麻。

这样基本上语音识别过程就完成了。

2:端到端的模型

现阶段深度学习在模式识别领域取得了飞速的发展,特别是在语音和图像的领域,因为深度学习的特性,在语音识别领域中,基于深度学习的声学模型现如今已经取代了传统的混合高斯模型GMM对于状态的输出进行建模,因此在普通的深度神经网络的基础之上,基于长短记忆网络的递归神经网络对语音序列的强大的建模能力进一步提高了语音识别的性能,但是这些方法依旧包含着最基础的隐马尔可夫HMM的基本结构,因此依旧会出现隐马尔科夫模型的训练和解码的复杂度问题.

基于深度学习的声学模型训练过程必须是由传统的混合高斯模型开始的,然后对训练数据集合进行强制的对齐,然后进行切分得到不同的声学特征,其实传统的方式并不利于对于整句话的全局优化,并且这个方法也需要额外的语音学和语言学的知识,比如发音词典,决策树单元绑定建模等等,搭建系统的门槛较高等问题.

一些科学家针对传统的声学建模的缺点,提出了链接时序分类技术,这个技术是将语音识别转换为序列的转换问题,这样一来就可以抛弃了传统的基于HMM的语音识别系统的一系列假设,简化了系统的搭建流程,从而可以进一步提出了端到端的语音识别系统,减少了语音对于发音词典的要求.

端到端的系统是由LSTM的声学建模方法和CTC的目标函数组成的,在CTC的准则下,LSTM可以在训练过程中自动的学习声学的特征和标注序列的对应关系,也就不需要再进行强制的对数据集合进行对齐的过程了.并且可以根据各种语种的特点,端到端识别直接在字或者单词上进行建模,但是因为端到端的识别可能是意味着发展的趋势,但是因为完全崛弃了语音学的知识,现如今在识别性能上仍然和传统的基于深度学习的建模方法有着一定的差距,不过我最近在看的一篇论文中,基于端到端的藏语识别已经达到甚至超过了现有的通用算法.

就拿藏语举例,藏语是一种我国的少数民族语言,但是因为藏族人口较少,相比起对于英文,汉语这样的大语种来说,存在着语音数据收集困难的问题,在上一篇文章中我们可以知道,自然语言处理的最重要的需求就是语料,如果有很好的语料库自然会事半功倍,这样就导致了藏语的语音识别研究工作起步较晚,并且因为藏语的语言学知识的匮乏进一步阻碍了藏语语音识别的研究的进展,在我国,藏语是属于一种单音节字的语言,在端到端的语音过程中,藏语是建模起来非常简单的一种语言,但是作为一种少数民族语言,语料不足会在训练过程中出现严重的稀疏性问题,并且很多人在研究现有的藏语词典中发现,如果完全崛弃现有的藏语发音词典,完全不利用这样的先验知识,这样其实也是不利于技术的发现的,因此现阶段下,采用CTC和语言知识结合的方式来建模,可以解决在资源受限的情况下声学的建模问题,使得基于端到端的声学模型方法的识别率超过当下基于隐马尔科夫的双向长短时记忆模型.

在基于CD-DNN-HMM架构的语音识别声学模型中,训练DNN通常需要帧对齐标签。在GMM中,这个对齐操作是通过EM算法不断迭代完成的,而训练DNN时需要用GMM进行对齐则显得非常别扭。因此一种不需要事先进行帧对齐的方法呼之欲出。此外对于HMM假设一直受到诟病,等到RNN出现之后,使用RNN来对时序关系进行描述来取代HMM成为当时的热潮。随着神经网络优化技术的发展和GPU计算能力的不断提升,最终使用RNN和CTC来进行建模实现了end-to-end语音识别的声学模型。CTC的全称是Connectionist Temporal Classification,中文翻译大概是连接时序分类。它要达到的目标就是直接将语音和相应的文字对应起来,实现时序问题的分类。

这里仍然可以描述为EM的思想:

E-step:使用BPTT算法优化神经网络参数;

M-step:使用神经网络的输出,重新寻找最有的对齐关系。

CTC可以看成是一个分类方法,甚至可以看作是目标函数。在构建end-to-end声学模型的过程中,CTC起到了很好的自动对齐的效果。同传统的基于CD-DNN-HMM的方法相比,对齐效果引用文章[Alex Graves,2006]中的图是这样的效果:

大数据
这幅图可以理解:基于帧对齐的方法强制要求切分好的帧对齐到对应的标签上去,而CTC则可以时帧的输出为空,只有少数帧对齐到对应的输出标签上。这样带来的差别就是帧对齐的方法即使输出是正确的,但是在边界区域的切分也很难准确,从而给DNN的训练引入错误。c) End-to-end模型由于神经网络强大的建模能力,End-to-end的输出标签也不再需要像传统架构一样的进行细分。例如对于中文,输出不再需要进行细分为状态、音素或者声韵母,直接将汉字作为输出即可;对于英文,考虑到英文单词的数量庞大,可以使用字母作为输出标签。从这一点出发,我们可以认为神经网络将声学符号到字符串的映射关系也一并建模学习了出来,这部分是在传统的框架中时词典所应承担的任务。针对这个模块,传统框架中有一个专门的建模单元叫做G2P(grapheme-to-phoneme),来处理集外词(out of vocabulary,OOV)。在end-to-end的声学模型中,可以没有词典,没有OOV,也没有G2P。这些全都被建模在一个神经网络中。另外,在传统的框架结构中,语音需要分帧,加窗,提取特征,包括MFCC、PLP等等。在基于神经网络的声学模型中,通常使用更裸的Fbank特征。在End-to-en的识别中,使用更简单的特征比如FFT点,也是常见的做法。或许在不久的将来,语音的采样点也可以作为输入,这就是更加彻底的End-to-end声学模型。除此之外,End-to-end的声学模型中已经带有了语言模型的信息,它是通过RNN在输出序列上学习得到的。但这个语言模型仍然比较弱,如果外加一个更大数据量的语言模型,解码的效果会更好。因此,End-to-end现在指声学模型部分,等到不需要语言模型的时候,才是完全的end-to-end。3、 语言模型(Language Model, LM)语言模型的作用可以简单理解为消解多音字的问题,在声学模型给出发音序列之后,从候选的文字序列中找出概率最大的字符串序列。

4、 解码传统的语音识别解码都是建立在WFST的基础之上,它是将HMM、词典以及语言模型编译成一个网络。解码就是在这个WFST构造的动态网络空间中,找到最优的输出字符序列。搜索通常使用Viterbi算法,另外为了防止搜索空间爆炸,通常会采用剪枝算法,因此搜索得到的结果可能不是最优结果。在end-to-end的语音识别系统中,最简单的解码方法是beam search。尽管end-to-end的声学模型中已经包含了一个弱语言模型,但是利用额外的语言模型仍然能够提高识别性能,因此将传统的基于WFST的解码方式和Viterbi算法引入到end-to-end的语音识别系统中也是非常自然的。然而由于声学模型中弱语言模型的存在,解码可能不是最优的。文章[yuki Kanda, 2016]提出在解码的时候,需要将这个若语言模型减掉才能得到最优结果。

End.

转载请注明来自36大数据(36dsj.com):36大数据 » NLP入门之语音模型原理

谷歌大神Jeff Dean:大规模深度学习最新进展

在AlphaGo与李世石比赛期间,谷歌天才工程师Jeff Dean在Google Campus汉城校区做了一次关于智能计算机系统的大规模深度学习(Large-Scale Deep Learning for Intelligent Computer Systems)的演讲。本文是对他这次演讲的总结。完整演讲视频(如下):

如果你无法理解信息里包含的内容,那么就会很难将其组织起来。

自从AlphaGo与李世石的比赛——这是约翰·亨利对战蒸汽锤的现代版本——吸引了全世界,再次滋生了对「人工智能毁灭世界」的恐惧感,似乎此时一睹Jeff的演讲是绝佳时刻。如果你认为AlphaGo现在很好,就等待它的beta版本吧。

Jeff当然提到了谷歌的著名语录:组织这个世界的信息,使信息唾手可得并变得有用。

过去,我们可能会将「组织」和收集、清除、存储、索引、报告和搜索数据联系起来。所有这些都是谷歌早期精通的业务。而这些任务完成后,谷歌已经开始进行下一项挑战了。

现在,组织意味着理解。

此次演讲的一些重点:

真正的神经网络由几亿个参数组成。谷歌现在所拥有的技能在于如何建造并快速训练这些大型模型来处理大量数据集,并用它们去解决实际问题,之后快速将这些模型部署到不同平台上的大量产品中(手机、传感器、云等等)。

神经网络在90年代没有得到快速发展是由于缺乏足够的计算能力和大型的数据集。你能看到谷歌对算法的天然热爱是如何与他们的大量基础设施结合到一起的,也能看到不断扩大的数据集如何为谷歌的人工智能创造了完美的推动。

谷歌和其他公司的一个关键区别就在于,当他们在2011年启动谷歌大脑计划时,他们并没有将他们的研究独立成该公司一个单独的研究部门,成为象牙塔一般的存在。而是项目团队和其他团队紧密合作,比如安卓、Gmail 和photo等部门,以确实改进它们的特性,解决困难的问题。这对每一家公司来说都是非常珍贵的一刻。通过和你的人一起工作将研究进行实际应用。

这一想法十分强大:他们知道他们能够获取完整的子系统,有些可能是机器学习到的,用更加通用的端对端的机器学习块进行替换。通常当你有很多复杂的子系统时,总会有很多复杂的代码将这些系统拼接起来。如果能够用数据和非常简单的算法将这一切进行替换的话就再好不过了。

机器学习很快将会变得更好。引用Jeff的话说:机器学习领域的发展非常快。一篇论文发布出来,一周内全球众多研究团体会下载这篇论文,阅读、解析论文,验证论文的内容,然后把自己对论文的延展发布到arXiv.org上。这与计算机学的其他领域不同,他们首先需要提交文件,而后六个月会议讨论决定是否接收,再过三个月会议上才会有结果。这就耗费了一年时间。电子论文能把这个时间压缩到一周是非常惊人的。

技术能够非常神奇的结合起来。谷歌翻译团队写了一个APP,能够使用计算机视觉在取景器上识别文本。在翻译完文本后,可以把翻译后的内容自动添加到图片上。另外一个例子是写图片字幕。把图片识别和一序列一序列的神经网络结合起来。可以想象,这些模块化的内容在未来将何等紧密的结合起来。

有强大功能的模型要小到足以在智能手机上运行。科技想要想取代智力必须走到这一步。它不能依靠网络连接外部的「云大脑」。既然TensorFlow模型能够在手机上运行,那这一点是有可能实现的。

如果你还没有思考深度神经网络如何解决数据理解问题,那你就要开始思考了。这条起始线从现在开始,但它的实现是非常明了的,我们看到了很多难题在深度学习网络面前都迎刃而解。

Jeff 发表的讲话都非常的棒,这次毫不例外。内容非常直接有趣,有深度,还非常容易理解。如果你想了解深度学习或了解Googel打算做什么,这些内容就值得一看了。

理解意味着什么?

当一个人看到街道景象时,他能轻而易举地挑选出图片上的文本,了解到有的商店卖纪念品,有家店价格特别低等信息。但直到现在,计算机依然不能从图片中提取出这些信息。

170007kiymh23gx8zg28i7.jpg

如果计算机想要从图片中了解现实世界,它需要能够从中挑选出有趣的信息点,阅读文本并理解它。

在未来,小型移动设备将主宰着计算机交互。这些设备都需要不同类型的界面。需要真的能够理解并生成对话。

我们在搜索引擎中输入:[汽车零部件]。旧的谷歌版本会因为关键词匹配给你第一条结果,但更好的结果其实是第二个结果。真正的理解是这个问题深层次的意义是什么,并非字眼的表面意义。这才是构建好的搜索与语言理解产品所需要的。

170008plfww7fk2woqw75o.jpg

谷歌深度神经网络小历史

谷歌大脑计划于2011年启动,聚焦于真正推动神经网络科学能达到的最先进的技术。

神经网络已经存在很多年了,出现于19世纪60年代至70年代之间,在80年代晚期和90年代早期红极一时,然后逐渐暗淡。主要因为两个问题:1)缺乏必备的计算能力去训练大量的模型,这意味着神经网络不能应用于包含大量有趣的数据集的大型问题。2)缺乏大量的有趣的数据集。

谷歌开始只有几个产品团队工作。随着这些团队发布一些很好的、能解决以前不能解决的问题的产品。名声渐起,很快,更多的团队加入其中帮助解决问题。

谷歌需要利用深度学习技术的产品/领域:安卓,Apps,药物发现,谷歌邮箱,图像理解,地图,自然语言,图片,机器人,语音翻译,等等。

深度学习能应用于如此完全不同的项目的原因是他们涉及相同的基石,这些基石可用于不同的领域:语音、文本、搜索查询、图像、视频、标签、实体(一种特定的软件模块)、文字、音频特性。你可以输入一种类型的信息,决定你想要输出信息类型,收集训练数据集指示出你想要计算的功能。然后,你可以放手不管了。

这些模型十分奏效,因为你输入的是非常原始的数据。你不必给出数据大量的有趣特点,模型的力量足以让它自动地通过观察许多许多例子决定数据集的有趣之处。

你可以学习常见的表征,这种学习很可能是跨领域的。例如,一辆『汽车』可以指图像中与真实相同的汽车。

他们已经学到他们可以聚集一大堆的子系统,其中一些可能是由机器学习的,然后用更通用的端对端的机器学习块代替它。通常当你有很多复杂的子系统时,往往有大量复杂的代码将这些子系统缝结在一起。如果你能用数据和简单的算法代替所有复杂代码,那就太好了。

什么是单个深度神经网络?

神经网络从数据中学习真正复杂的函数。从一端输入内容转换成另一端的输出内容。

这一函数不像计算x2,而是真正复杂的函数。当你输入原始像素,比如一只猫是,输出结果就会是事物的类别。

170050i80a2do1o3zy80yg.png

深度学习中的「深度」是指神经网络的层的数量。

对于深度,一个好的属性是系统是由简单的可训练的数学函数的集合构成的。

深度神经网络与大量机器学习方式是兼容的。

例如,你输入猫的图片,输出的是一张人为标注为猫的图像,这叫作监督式学习。你可以给系统列举大量的监督式样例,并且将学习结合一个函数,这个函数与在监督式例子所描述的是相似的。

你也可以进行非监督式训练,你只得到图像而不知道图像里面的什么。然后系统可以依靠在众多图片中出现的模式学会挑选。所以,即使不知道图像叫作什么,它也可以在所有这些有猫的图形辨别出共同的事物来。

这也和更多像强化学习这样的外来技术是兼容的。强化学习是非常重要的技术,它正在被AlphaGo使用。

什么是深度学习?

神经网络模型可以说是基于我们所认识的大脑运作的方式,它并不是对神经元真正工作的详细模拟,而是一个简单抽象的神经元版本。

170008hwjxwajxw66wawwm.jpg

一个神经元能够接收许多输入信息,真实的神经元会将不同的优势(strengths)与不同的输入相联系。人工智能网络试着学习为所有那些边缘,亦即与这些不同输入关联的优势进行加权。

真实的神经元吸收一些输入与优势的组合,并决定是否发出一个脉冲。人工神经元不仅仅会发出脉冲,还会发出一个实数值。这些神经元计算的函数是输入的加权求和乘以非线性函数的权重。

现今通常所用的非线性函数是ReLU(max(0,x))。在上世纪九十年代,大部分非线性函数都是更加平滑 (https://www.quora.com/What-is-special-about-rectifier-neural-units-used-in-NN-learning)的 sigmoid或tanh函数。当神经元不放电的时候会取真正的零值,而不是非常接近零的数值的优秀特性,从而帮助优化系统。

例如,如果神经元有着三个输入X1,X2,X3,分别有着0.21,0.3,0.7的权重,那么计算函数将为:y = max(0, -.0.21*x1 + 0.3*x2 + 0.7*x3)。

在识别图片里是一只猫还是一只狗的过程中,图像会经过多层级处理,基于它们的输入神经元可以决定是否发射脉冲。

170008mv90e91mit1zwtm1.jpg

最底层的神经元只处理一小部分像素,更高层的神经元则会处理下层神经元的输出并决定是否发射脉冲。

模型会如此向上直至最后一层处理完毕,举个例子,这是一只猫。在这种情况下它错了,这是一只狗(尽管我也认为那是一只猫,那是一只在篮子里的狗吗?)。

输出错误的信号会反馈回系统中,接着其余模型会做出调整以让它在下一次处理图片时更有可能给出正确的答案。

调整整个模型所有的边缘权重以增大获得正确结果的可能性,这就是神经网络的目标。人们在所有的样本都如此处理,这样在大部分的样本中都会得到正确的输出。

学习算法非常简单。循环计算步骤如下:

随机选择一个训练样本「(输入,标签)」。例如,一张猫的图片,以及预期输出「猫」。

用「输入」运行神经网络,并观察它的结果。

调整边缘权重,让输出更接近与标签」。

该如何调整边缘权重以让输出接近标签呢?

反向传播法:这里是一篇针对此的推荐文章:Calculus on Computational Graphs: Backpropagation (http://colah.github.io/posts/2015-08-Backprop/)。

当神经网顶层选择的是猫而不是狗的时候,通过微积分链式法则来调整权重参数使得网络可以做更准确的预测。

170008znz6akknu8k6v7as.jpg

你需要和权重的箭头保持同一方向,让它更有可能认为这是一只狗。不要跳一大步,因为这可是一个复杂坎坷的表面。小步前进会让结果在下一次更有可能变成狗。通过大量迭代以及对样本的观察,结果就越有可能变成狗。

通过链式法则你可以理解底层的参数变化会如何影响输出。这意味着神经网络网络的变化如同涟漪般波及至输入,调整整个模型,并增大它说出狗的可能性。

真的神经网络由数以亿计参数组成,因此你正在一个亿维空间内做调整,并试着理解那是怎样影响网络输出结果的。

神经网络的很多优秀特性

神经网络可以运用到多个不同领域,用来解决不同的问题:

文本:英语和其他语言包含数万亿的单词。现有很多对应的文字资料,包含句与句对应的一种源语言文字与其翻译版的另一种语言文字。

视觉数据:数十亿的图像和视频。

声音:每天会产生几万小时的音频数据;

用户行为:不同的应用程序都在产生数据,无论你在搜索引擎敲下的字符还是在邮箱里标记的垃圾邮件,这些用户行为里可以不断被学习,并用来给你「定制」智能系统。

知识图谱:数十亿打标签的RDF triple数据。

你给的数据越多,其反馈的结果越好,你也会让这个模型更大。

如果你投入更多的数据却不去扩大你的模型,会进入一个模型能力的饱和状态,此时,模型学习到的只是关于你的数据集最显而易见的事实。

通过增加模型的规模,模型不仅可以记住一些明显的特征,还会记住一些只是偶然在数据集中出现的细微特征。

打造更大的模型需要更多数据和更强大的计算能力。谷歌一直在做的就是如何规模化计算量并投入到这些问题的解决中,从而训练更大的模型。

深度学习给谷歌带来哪些影响?

语音识别

语音识别团队第一个和谷歌大脑团队合作部署神经网络。在谷歌大脑团队帮助下,部署上线了一个新的、基于神经网络的语音模型,不再使用之前的隐马尔科夫模型。

声学模型的问题是从150毫秒的语音里预测其中10毫秒的声音是什么。类似与「ba」还是「ka」。接着你有了这些预测的完整序列,然后将它们和语言模型对接起来,以理解用户在说什么。

这个模型将识别错误率降低了30%,意义非常重大。此后语音团队继续在构建更加复杂的模型,并结合更好的神经网络降低错误率。现在你在手机上说话,语音识别已经比三到五年前好太多了。

Image 挑战赛

大约六年前, ImageNet的数据库公开,大约有100万图像数据,这个巨大的图像数据库对于推进计算机视觉的发展意义重大。

图像被分为1000个不同种类,每个种类大约1000张照片;

大约有1000张不同的豹子照片、1000张不同的汽车、滑板车照片等等;

其中有个复杂的因素:并非所有的标签都是正确的;

比赛的目标是概括出照片的新的类型。对于一张新照片,你能判断出来上面是猎豹还是樱桃吗?

在神经网络运用到比赛之前,这项比赛的错误率为26℅。2014年,谷歌赢得比赛时的错误率为6.66%。2015年的时候,获胜团队的错误率降低到3.46%。

这是一个巨大而且有深度的模型。每个盒子都布满了完整层级的神经元,它们正在进行卷积运算,关于这方面的详细情况,可以查看这篇论文《Going Deeper with Convolutions》

170008vm9rb9h9j5jqabzi.jpg

一个名叫 Andrej Karpathy 的人也参与了比赛,他的错误率是5.1%,他后来还写了篇文章《What I learned from competing against a ConvNet on ImageNet.》

神经网络模型擅长什么?

神经网络模型非常擅长识别精细程度的差别。比如,计算机擅长辨别人类不善于分辨的犬种。人类可能看到一朵花就只知道那是一朵花,计算机可以分辨那是一朵「芙蓉」或是一朵「大丽花」。

神经网络模型擅长归纳。比如不同种类的饭菜,尽管看起来不一样,但都会被标记为「饭菜」。

当计算机出错时,错误的原因是合理的。比如一只蛞蝓看起来很像一条蛇。

谷歌照片搜索

检查照片的像素并理解图像中的内容,这是个很强大的能力。

Google Photos 团队在没有标记它们的情况下部署了这一能力。你可以在没有标记图片的情况下搜索到雕像、尤达、图画、水等图片。

街景影像

在街景影像中,你希望可以阅读到所有的文本。这是更为精细更为具体的视觉任务。

首先需要能够找到图像中的文本。模型基本上都是被训练用来预测像素热图的:哪些像素包含文本,哪些不包含。训练数据是绘制于文本像素周围的多边形。

因为训练数据包含不同的字符集,它可以找到多种不同语言的文本。它可以识别大字体和小字体,离镜头近的和离得很远的文字,以及不同颜色的文本。

这是一个训练相对简单的模型。这是一个试图预测每个像素是否包含文本的传统的网络。

谷歌搜索排名的RankBrain

RankBrain于2015年推出,是谷歌第三重要的搜索排名因素。了解更多:谷歌将其利润丰厚的网络搜索交给人工智能机器。

搜索排名是不同的,因为你想要能够理解该模型,你想理解为什么它会做出特定的决策。

这是搜索排名团队犹豫在搜索排名中使用神经网络的一个原因。当系统出错时,他们希望了解什么会这样。

调试工具已被制造出来,而且模型也能被充分地理解,以克服这种异议。

一般来说你不想手动调整参数。你尝试理解为什么模型会做出那样的预测并搞清楚是否与训练数据相关,是与问题不匹配吗?你可能在一个分布式数据上进行训练,然后将其应用于另一个。通过搜索查询的分布,模型每天都能获得一点改变。因为事件在改变,模型也一直在改变。你必须了解你的分布是否是稳定的,比如在语音识别中,人们的声音并不会发生太大改变。查询和文档内容经常在改变,所以你必须确保你的模型是新鲜的。更一般地,我们需要打造更好的用于理解这些神经网络内部状况的工具,搞清楚是什么得出了预测。

序列至序列(Sequence-to-Sequence)映射模型

世界上许多问题都可归入到一个序列映射到另一个序列的框架中。谷歌的Sutskever、Vinyals 和 Le 在这个主题上写了一篇开关性的论文:使用神经网络的序列到序列学习 (http://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf)。

特别地,他们研究了语言翻译,将英语翻译成法语中的问题。翻译事实上只是将英语句子序列映射到法语句子序列。

神经网络非常擅长学习非常复杂的功能,所以这个模型学习了映射英语句子到法语句子的功能。

170009nfzopeod6jkhp6pr.jpg

一种语言的一个句子通过EOS(end of sentence)信号一次输入一个词。当模型看到EOS 开始产出其它语言对应的句子时,模型就得到了训练。训练数据是具有同样含义的不同语言中的配对句子。它只是试图该函数建模。

模型会在每一步发出你的词汇中所有词条输入的概率分布。在推理而不是训练时间,你需要做一点搜索。如果你必须最大化每个词的概率,你并不一定会得到最可能的句子。直到找到最大可能的句子,联合概率的搜索才完成。

该系统是现在公共翻译服务中最先进的。其它翻译系统是一堆手写的代码或这个翻译问题的子块的机器学习模型,而非完全的端到端学习系统。

人们对这一模型的兴趣在暴增,因为很多问题都可被映射到序列到序列的方法。

智能回复(Smart Reply)

Smart Reply是序列到序列在产品中的一个应用案例。在手机上,你希望快速回复邮件,而打字又让人痛苦。

和 Gmail 团队合作,他们开发了一个能预测一条信息可能的回复的系统。

第一步是训练一个小模型以预测一条信息是否是可以快速回复的信息。如果是,就会激活一个更大的计算上更昂贵的模型;该模型将该信息作为一个序列,并尝试预测回复的单词序列。

比如,对于一封询问感恩节邀请的电子邮件,可预测到的回复有三个:把我们算上;我们会去;抱歉我们去不了。

Inbox 应用中惊人数量的回复都是通过 Smart Reply 生成的。

图片说明

生成一张图片说明时,你会试着让机器尽可能写出类似人类基于图片会做出的说明。

采用已经开发出来的图片模型,以及已经研发出来的Sequence-to-Sequence模型,把它们插在一起。图片模型被用作输入。

它被训练用来生成说明。训练数据集拥有五种不同的人给出的五种不同说明的图片。10万到20万的图片需要写70万句的说明。

一张婴儿怀抱泰迪熊的图片,电脑这么写的:一个抱着填充玩具动物孩子的特写;一个婴儿在泰迪熊旁边睡着了。

还没有达到人类理解水平,但机器出错时,结果可能会有趣。

综合视觉+翻译

技术能够综合起来。翻译团队编写了使用了在取景器中识别文本的计算机视觉APP。翻译文本,然后给图片叠加翻译文本(让人印象非常深刻,约37;29)。

模型足够小,整个计算都在设备上运行。

迭代(turnaround)时间和对研究的影响

在一天内完成单个CPU花费6周才能完成的训练

谷歌真的关心能够快速迭代研究。它的想法是快速的训练模型。理解什么运行良好,什么运行欠佳,找出下一组要运行的实验。

一个模型应该在在几分钟几小时内就能可训练,而不是几天甚至几个礼拜。让每个做这类研究的人更加富有生产力。

如何快速训练模型?

模型的并行性

一个神经网络有许多内在的并行性。

所有不同的个体神经元几乎都是彼此独立的,当你计算它们时,特别是,加入你有Local Receptive Fields,这是一个神经元从其下方少量神经元那里接受输入的地方。

能够跨越不同GPU卡上的不同机器对工作进行划分,只有跨越边界的数据才需要交流。

170010ll6vm9qjd2q96doh.jpg

数据的并行性

当你对模型的参数集进行优化时,不应该在中央服务的一台机器上进行,这样你就有不同的模型副本,通过它们之间的合作来进行参数优化。

在训练中理解不同的随机数据片段。每一个副本都会获得模型中当前的参数集,通过对相当规模数据的理解来判断出梯度,找出需要对参数所作的调整,并且将调整值发回至中央参数集服务器。参数服务器会对参数进行调整。不断重复这个过程。

这会在多个副本之间完成。有时他们会使用500台机器来生成500个模型副本,以便迅速实现参数的优化和处理数据。

这个过程可以异步进行,每个数据分任务在各自独自的循环运算中,获取参数,计算梯度并将它们传回,不会受到其他彼此的控制和同步。结果是,按照50-100的副本规模进行练习,对许多模型来说是可行的。

Q&A

如果不是诸如谷歌这样的大公司,无法获取海量数据集,你会怎么做?从一个运行良好的模型开始,用公共数据集进行训练。公共数据集普遍可以获取。然后用更加适合你问题的数据进行训练。当你从一个类似并且公开可获取的数据组开始时,针对你的特殊问题,可能只需要1,000或者10,000标签实例。ImageNet就是这种处理可行的好例子。

身为一个工程师,你所犯过的最大错误是什么?没有在BigTable里放入分布式事务处理能力。如果你想要更新多条数据,你不得不运作你自己的事务处理流程。没有放入事务处理能力是因为会增加系统设计的复杂度。回想起来,很对团队想要有那种能力,他们各自独立(在上层)去添加这个能力,也获得了不同程度成功。我们应该在核心系统实现事务处理能力。它在内部应用场景也会很有用。Spanner系统增加了事务处理搞定了这个问题。

英文链接:Jeff Dean on Large-Scale Deep Learning at Google