数据挖掘(十)
文章目录
物体分类应用场景和目标
- 我们可以查看图像数据,压缩包包含文件data_batch_1, data_batch_2等以及test_batch,这些文件使使用cPickle生成的对象。
import os
import pickle
import numpy as np
from matplotlib import pyplot as plt
data_folder = os.path.join(os.getcwd(), 'data_mining', 'cifar-10-batches-py')
batch1_filename = os.path.join(data_folder, 'data_batch_1')
def unpickle(filename):
with open(filename, 'rb') as fo:
return pickle.load(fo, encoding='latin1')
batch1 = unpickle(batch1_filename)
image_index = 100
image = batch1['data'][image_index]
image = image.reshape((32, 32, 3), order='F')
image = np.rot90(image, -1)
plt.imshow(image)
- 计算机视觉技术应用范围很广。在线地图网站,自动为街景中的人脸添加模糊效果,以保护被拍摄到的人们的隐私。人脸识别技术在很多行业得到应用,比如照相机自动识别人脸以提升拍摄质量以及识别照片中的人脸等。航天工业使用计算机技术实现数据采集的自动化等等。
深度神经网络
- 深度神经网络是至少包含两层隐含层的神经网络。实际的深度神经网络通常规模很大,每层神经元数量和层次都非常多。神经网络接收很基础的特征作为输入,对于计算机视觉来说,输入为简单的像素值。神经网络算法把这些数据整合起来向网络中传输,基本的特征组合成复杂的特征。
- 神经网络规模很大,实现不好,运行时间会很长,甚至还会出现内存不足,最后无法运行的情况。基本实现可以从创建神经元类开始,多个神经元组成层类,每一层的神经元使用边这个类的一个实例连接到另一层神经元。基于类的实现,有助于显示网络的工作方式,但是对于创建大型网络,效率很低。神经网络的核心就是一系列矩阵运算。两个网络之间连接的权重可以用矩阵来表示,其中行表示第一层的神经元,列表示第二层神经元。矩阵的每个元素表示位于不同层的两个神经元之间连接的权重。
- Theano是用来创建和运行数学表达式的工具,在Theano中,我们定义函数要做什么而不是怎么做,这样它就能以最佳的方式对表达式进行求职,还可以进行延迟计算。我们可以使用Theano来定义函数,处理标量、数组和矩阵以及其他数学表达式。
import theano
from theano import tensor as T
a = T.dscalar()
b = T.dscalar()
c = T.sqrt(a**2 + b**2)
f = theano.function([a, b], c)
f(3, 4)
- Lasagne库是用来构建神经网络的,使用Theano进行计算。Lasagne实现了集中比较新的神经网络层和组成这些层的模块。内置网络层、删除层和噪音层。使用卷积层模拟人类视觉工作原理,使用少量相互连接的神经元,分析一部分输入值,便于神经网络实现对数据的标准转换。视觉分析实验就是用卷积层对图像进行转换。神经网络使用卷积层和池化层,池化层接收某个区域最大输出值,可以降低图像中的微笑变动带来的噪音,减少信息量。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import lasagne
iris = load_iris()
X = iris.data.astype(np.float32)
y_true = iris.target.astype(np.int32)
X_train, X_test, y_train, y_test = train_test_split(X, y_true, random_state=14)
input_layer = lasagne.layers.InputLayer(shape=(10, X.shape[1]))
hidden_layer = lasagne.layers.DenseLayer(input_layer, num_units=12, nonlinearity=lasagne.nonlinearities.sigmoid)
output_layer = lasagne.layers.DenseLayer(hidden_layer, num_units=3, nonlinearity=lasagne.nonlinearities.softmax)
- 依照Lasagne的用法,输出层作为我们的神经网络。当我们输入一条数据到神经网络时,它查看输出层,向上回溯找到向输出层提供输入的那一层。这个过程重复进行直到到达输入层,因为输入层没有上一层,所以就要把要处理的数据交给输入层处理。输入层的激活函数把接收到的数据处理后输出给调用它的层,然后再一步步在网络中传播直到输出层。
import theano
import theano.tensor as T
import numpy as np
from sklearn.metrics import f1_score
net_input = T.matrix('net_input')
net_output = output_layer.get_output(net_input)
true_output = T.ivector('true_output')
loss = T.mean(T.nnet.categorical_crossentropy(net_output, true_output))
all_params = lasagne.layers.get_all_params(output_layer)
updates = lasagne.updates.sgd(loss, all_params, learning_rate=0.1)
train = theano.function([net_input, true_output], loss, updates)
get_output = theano.function([net_input], net_output)
for n in range(1000):
train(X_train, y_train)
y_output = get_output(X_test)
y_pred = np.argmax(y_output, axis=1)
print(f1_score(y_test, y_pred))
- nolearn对Lasagne进行了封装,使用nolearn无法对一些细节进行调整,但是代码可读性更强,也更容易管理。nolearn实现了几种常见的复杂程度很高的神经网络。以识别图像中字母的实验为例。在nolearn中实现神经网络,只需要定义它由Lasagne哪几种类型的层组成就行。
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from skimage.transform import resize
from skimage import transform as tf
from skimage.measure import label, regionprops
from sklearn.utils import check_random_state
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from lasagne import layers, updates
from nolearn.lasagne import NeuralNet
from lasagne.nonlinearities import sigmoid, softmax
def create_captcha(text, shear=0, size=(100,24)):
im = Image.new('L', size, 'black')
draw = ImageDraw.Draw(im)
font = ImageFont.truetype(r'Coval.otf', 22)
draw.text((2, 2), text, fill=1, font=font)
image = np.array(im)
affine_tf = tf.AffineTransform(shear)
image = tf.warp(image, affine_tf)
return image/image.max()
def segment_iamge(image):
labeled_image = label(image > 0)
subimages = []
for region in regionprops(labeled_image):
start_x, start_y, end_x, end_y = region.bbox
subimages.append(image[start_x:end_x, start_y:end_y])
if len(subimages) == 0:
return [image,]
return subimages
random_state = check_random_state(14)
letters = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
shear_values = np.arange(0, 0.5, 0.05)
def generate_sample(random_state=None):
random_state = check_random_state(random_state)
letter = random_state.choice(letters)
shear = random_state.choice(shear_values)
return create_captcha(letter, shear, size=(20, 20)), letters.index(letter)
dataset, targets = zip(*(generate_sample(random_state) for i in range(3000)))
dataset = np.array(dataset, dtype='float')
targets = np.array(targets)
onehot = OneHotEncoder()
y = onehot.fit_transform(targets.reshape(targets.shape[0], 1))
y = y.todense().astype(np.float32)
dataset = np.array([resize(segment_iamge(sample)[0], (20, 20)) for sample in dataset])
X = dataset.reshape((dataset.shape[0], dataset.shape[1]*dataset.shape[2]))
X = X/X.max()
X = X.astype(np.float32)
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.9, random_state=14)
layers = [('input', layers.InputLayer),
('hidden', layers.DenseLayer),
('output', layers.DenseLayer),]
net1 = NeuralNet(layers, input_shape=X.shape, hidden_num_units=100, output_num_units=26,
hidden_nonlinearity=sigmoid, output_nonlinearities=softmax, hidden_b = np.zeros((100,), dtype=np.float64),
update=updates.momentum, update_learning_rate=0.9, update_momentum=0.1, regression=True, max_epochs=1000)
net1.fit(X_train, y_train)
y_pred = net1.predict(X_test)
y_pred = y_pred.argmax(axis=1)
if len(y_test.shape) > 1:
y_test = y_test.argmax(axis=1)
print(f1_score(y_test, y_pred))
应用
- 我们使用CIFAR数据集,创建深度卷积神经网络,然后在虚拟机上使用GPU来运行。
import numpy as np
batches = []
for i in range(1, 6):
batch_filename = os.path.join(data_folder, 'data_batch_{}'.format(i))
batches.append(unpickle(batch_filename))
break
X = np.vstack([batch['data'] for batch in batches])
X = np.array(X)/X.max()
X = X.astype(np.float32)
- 类别数据的处理方法类似,但是我们使用hstack函数,在数组末尾追加一列数据。然后使用OneHotEncoder把它转换为只含有一位有效编码的数组。
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
y = np.hstack(batch['labels'] for batch in batches).flatten()
y = OneHotEncoder().fit_transform(y.reshape(y.shape[0], 1)).todense()
y = y.astype(np.float32)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
X_train = X_train.reshape(-1, 3, 32, 32)
X_test = X_test.reshape(-1, 3, 32, 32)
- 创建神经网络
from lasagne import layers
from nolearn.lasagne import NeuralNet
from lasagne.nonlinearities import sigmoid, softmax
from sklearn.metrics import f1_score
layers=[
('input', layers.InputLayer),
('conv1', layers.Conv2DLayer),
('pool1', layers.MaxPool2DLayer),
('conv2', layers.Conv2DLayer),
('pool2', layers.MaxPool2DLayer),
('conv3', layers.Conv2DLayer),
('pool3', layers.MaxPool2DLayer),
('hidden4', layers.DenseLayer),
('hidden5', layers.DenseLayer),
('output', layers.DenseLayer),
]
nnet = NeuralNet(layers=layers,
input_shape=(None, 3, 32, 32),
conv1_num_filters=32,
conv1_filter_size=(3, 3),
conv2_num_filters=64,
conv2_filter_size=(2, 2),
conv3_num_filters=128,
conv3_filter_size=(2, 2),
pool1_ds=(2,2),
pool2_ds=(2,2),
pool3_ds=(2,2),
hidden4_num_units=500,
hidden5_num_units=500,
output_num_units=10,
output_nonlinearity=softmax,
update_learning_rate=0.01,
update_momentum=0.9,
regression=True,
max_epochs=3,
verbose=1)
nnet.fit(X_train, y_train)
y_pred = nnet.predict(X_test)
print(f1_score(y_test.argmax(axis=1), y_pred.argmax(axis=1)))