首页 理论教育 手写数字竞赛:9月3日活动精彩纷呈!

手写数字竞赛:9月3日活动精彩纷呈!

时间:2023-06-28 理论教育 版权反馈
【摘要】:以Kaggle上的手写数字数据集竞赛为例子,通过mxnet定义卷积神经网络,并在GPU上快速训练模型。建模LeNet神经网络结构是由Yann LeCun提出的,并用于识别手写数字,也是最早的卷积神经网络之一。>data<-mx.symbol.Variable′#第一个卷积>conv1<-mx.symbol.Convolution>tanh1<-mx.symbol.Activation>pool1<-mx.symbol.Pooling#第二个卷积>conv2<-mx.symbol.Convolution>tanh2<-mx.symbol.Activation>pool2<-mx.symbol.Pooling#第一个全连接>flatten<-mx.symbol.Flatten>fc1<-mx.symbol.FullyConnected>tanh3<-mx.symbol.Activation#第二个全连接>fc2<-mx.symbol.FullyConnected>lenet<-mx.symbol.SoftmaxOutput #损失函数为了让输入数据的格式能对应LeNet,需要将数据变成R中的array格式。

手写数字竞赛:9月3日活动精彩纷呈!

【例9.3】以Kaggle上的手写数字数据集(MNIST)竞赛为例子,通过mxnet定义卷积神经网络,并在GPU上快速训练模型。

(1)数据准备

从Kaggle上下载数据,并将它们放入“data/”文件夹中。然后读入数据,并做一些预处理工作。

>require(mxnet)

>train<-read.csv(data/train.csv,header=TRUE)

>test<-read.csv(data/test.csv,header=TRUE)

>train<-data.matrix(train)

>test<-data.matrix(test)

>train.x<-train[,-1]

>train.y<-train[,1]

>train.x<-t(train.x/255)

>test<-t(test/255)

最后两行预处理的作用有两个:

1)原始灰度图片数值处在[0,255]之间,将其变换到[0,1]之间。

2)mxnet接受像素X图片的输入格式,所以对输入矩阵进行了转置。

(2)建模

LeNet神经网络结构是由Yann LeCun提出的,并用于识别手写数字,也是最早的卷积神经网络之一。同样地,这里使用Symbol语法来定义,不过这个结构会比较复杂。

>data<-mx.symbol.Variable(data

#第一个卷积

>conv1<-mx.symbol.Convolution(data=data,kernel=c(5,5),num_filter=20)

>tanh1<-mx.symbol.Activation(data=conv1,act_type="tanh")

>pool1<-mx.symbol.Pooling(data=tanh1,pool_type="max",

kernel=c(2,2),stride=c(2,2))

#第二个卷积

>conv2<-mx.symbol.Convolution(data=pool1,kernel=c(5,5),

num_filter=50)

>tanh2<-mx.symbol.Activation(data=conv2,act_type="tanh")

>pool2<-mx.symbol.Pooling(data=tanh2,pool_type="max",

kernel=c(2,2),stride=c(2,2))

#第一个全连接

>flatten<-mx.symbol.Flatten(data=pool2)

>fc1<-mx.symbol.FullyConnected(data=flatten,num_hidden=500)

>tanh3<-mx.symbol.Activation(data=fc1,act_type="tanh")

#第二个全连接

>fc2<-mx.symbol.FullyConnected(data=tanh3,num_hidden=10)

>lenet<-mx.symbol.SoftmaxOutput(data=fc2) #损失函数

为了让输入数据的格式能对应LeNet,需要将数据变成R中的array格式。

>train.array<-train.x

>dim(train.array)<-c(28,28,1,ncol(train.x))

>test.array<-test

>dim(test.array)<-c(28,28,1,ncol(test))

接下来,分别使用CPU和GPU来训练这个模型,从而展现不同的训练效率

>n.gpu<-1

>device.cpu<-mx.cpu()

>device.gpu<-lapply(0:(n.gpu-1),function(i){mx.gpu(i)})

将GPU的每个核以list的格式传递进去,如果有BLAS等自带矩阵运算并行的库存在,则没必要对CPU这么做了。

先在CPU上进行训练,只进行一次迭代。

>mx.set.seed(0)

>tic<-proc.time()

>model<-mx.model.FeedForward.create(lenet,

X=train.array,

y=train.y,

ctx=device.cpu,

num.round=1,

array.batch.size=100,

learning.rate=0.05,

momentum=0.9,

wd=0.00001,

eval.metric=mx.metric.accuracy,

epoch.end.callback=mx.callback.log.train.metric(100))(www.xing528.com)

Starttrainingwith1devices

Batch[100]Train-accuracy=0.1066

Batch[200]Train-accuracy=0.16495

Batch[300]Train-accuracy=0.401766666666667

Batch[400]Train-accuracy=0.537675

[1]Train-accuracy=0.557136038186157

print(proc.time()-tic)

user system elapsed

130.030204.97683.821

在CPU上训练一次迭代一共花了83 s。接下来在GPU上训练5次迭代:

mx.set.seed(0)

tic<-proc.time()

model<-mx.model.FeedForward.create(lenet,

X=train.array,

y=train.y,

ctx=device.gpu,

num.round=5,

array.batch.size=100,

learning.rate=0.05,

momentum=0.9,

wd=0.00001,

eval.metric=mx.metric.accuracy,

epoch.end.callback=mx.callback.log.train.metric(100))

Start training with 1 devices

Batch[100]Train-accuracy=0.1066

Batch[200]Train-accuracy=0.1596

Batch[300]Train-accuracy=0.3983

Batch[400]Train-accuracy=0.533975

[1]Train-accuracy=0.553532219570405

Batch[100]Train-accuracy=0.958

Batch[200]Train-accuracy=0.96155

Batch[300]Train-accuracy=0.966100000000001

Batch[400]Train-accuracy=0.968550000000003

[2]Train-accuracy=0.969071428571432

Batch[100]Train-accuracy=0.977

Batch[200]Train-accuracy=0.97715

Batch[300]Train-accuracy=0.979566666666668

Batch[400]Train-accuracy=0.980900000000003

[3]Train-accuracy=0.981309523809527

Batch[100]Train-accuracy=0.9853

Batch[200]Train-accuracy=0.985899999999999

Batch[300]Train-accuracy=0.986966666666668

Batch[400]Train-accuracy=0.988150000000002

[4]Train-accuracy=0.988452380952384

Batch[100]Train-accuracy=0.990199999999999

Batch[200]Train-accuracy=0.98995

Batch[300]Train-accuracy=0.990600000000001

Batch[400]Train-accuracy=0.991325000000002

[5]Train-accuracy=0.991523809523812

>print(proc.time()-tic)

user system elapsed

9.2881.6806.889

在GPU上训练5轮迭代只花了不到7 s,快了数十倍!可以看出,对于这样的网络结构,GPU的加速效果是非常显著的。有了快速训练的办法,可以很快地做预测,并且提交到Kaggle上。

>preds<-predict(model,test.array)

>pred.label<-max.col(t(preds))-1

>submission<-data.frame(ImageId=1:ncol(test),Label=pred.label)

>write.csv(submission,file=submission.csv,row.names=FALSE,

quote=FALSE)

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈