数据挖掘(十)

数据挖掘(十)

文章目录

对于去欸的那个图像中的物体,我们使用像素值作为神经网络的输入值,自动找到有用的像素组合,形成更高层级的特征,然后将其用于实际的分类。

物体分类应用场景和目标

我们构建一个系统,接收图像,给出图像里面使什么物体。系统好比是自动驾驶汽车的视觉系统,能够发现道路及两侧的任何故障。我们使用CIFAR-10数据集作为图像数据来源,它含有6万张32像素见方的图像,有10种类型,每个图像都有一个RGB值。这个数据集已经分为训练集和测试集两部分,有5万张训练图像和1万张测试图片。每种类型含有1万张图片。数据集有airplane、automobile、bird、cat、deer、dog、frog、horse、ship和truck十种类型。所有图像已经转换为numpy数组。

  1. 我们可以查看图像数据,压缩包包含文件data_batch_1, data_batch_2等以及test_batch,这些文件使使用cPickle生成的对象。
python 复制代码
import os
import pickle
import numpy as np
from matplotlib import pyplot as plt
# 加载CIFAR-10数据集的第一批数据
data_folder = os.path.join(os.getcwd(), 'data_mining', 'cifar-10-batches-py')
batch1_filename = os.path.join(data_folder, 'data_batch_1')
# 读取第一批图像文件数据,这些图像数据文件格式为pickle
def unpickle(filename):
    with open(filename, 'rb') as fo:
	# 由于数据集的pickle文件是由python2生成的,使用python3打开需要把编码设置成latin
        return pickle.load(fo, encoding='latin1')
# 加载数据集,batch1是一个字典结构,包含numpy数组形式的图像数据、图像类别、文件名以及该批文件的简短说明
batch1 = unpickle(batch1_filename)
# 以data为键,从字典中渠道存储这一批图像数据的列表后,再用图像索引号就能取到其中一张图像的数据
image_index = 100
image = batch1['data'][image_index]
# 图像数据格式与matplotlib所使用的有所不同,因此显示图像前需要改变数组的形状,对矩阵进行转换,这种数据格式不会影响神经网络训练,但是绘图时需要进行数据格式转换
image = image.reshape((32, 32, 3), order='F')
image = np.rot90(image, -1)
# 创建图像对象并配置其属性,但不会显示图像,图像的分辨率很低只有32像素见方
plt.imshow(image)
  1. 计算机视觉技术应用范围很广。在线地图网站,自动为街景中的人脸添加模糊效果,以保护被拍摄到的人们的隐私。人脸识别技术在很多行业得到应用,比如照相机自动识别人脸以提升拍摄质量以及识别照片中的人脸等。航天工业使用计算机技术实现数据采集的自动化等等。

深度神经网络

  1. 深度神经网络是至少包含两层隐含层的神经网络。实际的深度神经网络通常规模很大,每层神经元数量和层次都非常多。神经网络接收很基础的特征作为输入,对于计算机视觉来说,输入为简单的像素值。神经网络算法把这些数据整合起来向网络中传输,基本的特征组合成复杂的特征。
  2. 神经网络规模很大,实现不好,运行时间会很长,甚至还会出现内存不足,最后无法运行的情况。基本实现可以从创建神经元类开始,多个神经元组成层类,每一层的神经元使用边这个类的一个实例连接到另一层神经元。基于类的实现,有助于显示网络的工作方式,但是对于创建大型网络,效率很低。神经网络的核心就是一系列矩阵运算。两个网络之间连接的权重可以用矩阵来表示,其中行表示第一层的神经元,列表示第二层神经元。矩阵的每个元素表示位于不同层的两个神经元之间连接的权重。
  3. Theano是用来创建和运行数学表达式的工具,在Theano中,我们定义函数要做什么而不是怎么做,这样它就能以最佳的方式对表达式进行求职,还可以进行延迟计算。我们可以使用Theano来定义函数,处理标量、数组和矩阵以及其他数学表达式。
python 复制代码
# 创建计算直角三角形斜边长度的函数
import theano
from theano import tensor as T
# a和b是简单的数值类型,使用标量
a = T.dscalar()
b = T.dscalar()
# 定义输出c,c既不是函数,也不是一个数值,是由a和b组成的表达式
c = T.sqrt(a**2 + b**2)
# 告诉theano创建一个函数,接收a、b,输出c
f = theano.function([a, b], c)
f(3, 4)
  1. Lasagne库是用来构建神经网络的,使用Theano进行计算。Lasagne实现了集中比较新的神经网络层和组成这些层的模块。内置网络层、删除层和噪音层。使用卷积层模拟人类视觉工作原理,使用少量相互连接的神经元,分析一部分输入值,便于神经网络实现对数据的标准转换。视觉分析实验就是用卷积层对图像进行转换。神经网络使用卷积层和池化层,池化层接收某个区域最大输出值,可以降低图像中的微笑变动带来的噪音,减少信息量。
python 复制代码
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)
# Lasagne对数据类型有特殊要求,需要把类别值住那换为int32类型
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的用法,输出层作为我们的神经网络。当我们输入一条数据到神经网络时,它查看输出层,向上回溯找到向输出层提供输入的那一层。这个过程重复进行直到到达输入层,因为输入层没有上一层,所以就要把要处理的数据交给输入层处理。输入层的激活函数把接收到的数据处理后输出给调用它的层,然后再一步步在网络中传播直到输出层。
python 复制代码
import theano
import theano.tensor as T
import numpy as np
from sklearn.metrics import f1_score
# 定义一个Theano表达式和函数,为神经网络的输入数据、输出结果和实际输出结果声明变量
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)
# 创建两个Theano函数,训练网络,然后获取网络的输出
train = theano.function([net_input, true_output], loss, updates)
get_output = theano.function([net_input], net_output)
# 调用训练函数,在训练集上进行一轮迭代,接收训练数据,预测类别,与给定类别作比较,更新特征权重以最小化损失。再进行1000此迭代,逐渐改进神经网络
for n in range(1000):
    train(X_train, y_train)
# 对输出计算F值以评估分类效果,y_output为输出层每个神经元的激励作用大小,找出记录作用最高的神经元就能得到预测结果
y_output = get_output(X_test)
# y_pred数组是预测结果数组
y_pred = np.argmax(y_output, axis=1)
# 计算F1值
print(f1_score(y_test, y_pred))
  1. nolearn对Lasagne进行了封装,使用nolearn无法对一些细节进行调整,但是代码可读性更强,也更容易管理。nolearn实现了几种常见的复杂程度很高的神经网络。以识别图像中字母的实验为例。在nolearn中实现神经网络,只需要定义它由Lasagne哪几种类型的层组成就行。
python 复制代码
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))

应用

  1. 我们使用CIFAR数据集,创建深度卷积神经网络,然后在虚拟机上使用GPU来运行。
python 复制代码
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语句是用来测试代码,减少训练数据,测试过代码能正常工作后可以删除
    break
# 把每批次的图像文件添加到数据集里,vstack方法往数组末尾追加一行数据
X = np.vstack([batch['data'] for batch in batches])   
# 把像素值归一化并强制为32位浮点型数据
X = np.array(X)/X.max()
X = X.astype(np.float32)
  1. 类别数据的处理方法类似,但是我们使用hstack函数,在数组末尾追加一列数据。然后使用OneHotEncoder把它转换为只含有一位有效编码的数组。
python 复制代码
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)
  1. 创建神经网络
python 复制代码
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)))
相关推荐
边缘计算社区16 分钟前
边缘计算与推理算力:智能时代的加速引擎
人工智能·边缘计算
OpenInfra18 分钟前
九州未来再度入选2024边缘计算TOP100
人工智能·边缘计算
谢眠31 分钟前
机器学习day1-数据集
人工智能·机器学习
友思特 智能感知44 分钟前
友思特方案 | 让笔划浮动:无代码的深度学习实现多领域的字符检测
人工智能·深度学习
深圳市青牛科技实业有限公司 小芋圆44 分钟前
为什么汽车电源正在用 48V 取代 12V
人工智能·单片机·嵌入式硬件·汽车·电脑·智能马桶
搬砖的小码农_Sky1 小时前
AI技术应用在电商方面的创新案例
人工智能
寻道模式2 小时前
【时间之外】IT人求职和创业应知【32】-RTE二次出现
人工智能·职场和发展
好难怎么办2 小时前
动手学深度学习-使用d2l导致jupyter内核挂掉
人工智能·深度学习·jupyter
小码编匠3 小时前
.NET 9 发布 性能提升、AI 支持与全方位改进
人工智能·后端·.net
AIAdvocate3 小时前
【金融风控】特征评估与筛选详解
人工智能·python·机器学习·金融·特征工程