本文章全为一个note, 代码来自zh.d2.ai. 目的在于自己看到这代码能想起来mxnet的基本用法.
import d2lzh as dd2l
from mxnet import autograd, gluon, init, nd
from mxnet.gluon import data as gdata, loss as gloss, nn
import numpy as np
import pandas as pd
train_data = pd.read_csv('data/kaggle_house_pred_train.csv')
test_data = pd.read_csv('data/kaggle_house_pred_test.csv')
# 获得数字特征
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:,1:]))
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
# 数字特征进行规则化
all_features[numeric_features] = all_features[numeric_features].apply(lambda x : (x - x.mean()) / x.std())
all_features[numeric_features] = all_features[numeric_features].fillna(0)
# 非数字特征进行数字化 get_dummies()
all_features = pd.get_dummies(all_features, dummy_na=True)
m_train = train_data.shape[0]
train_features = nd.array(all_features.iloc[0:m_train, :])
test_features = nd.array(all_features.iloc[m_train:, :])
train_labels = nd.array(train_data.iloc[:, -1]).reshape((-1, 1))
loss = gloss.L2Loss()
def get_net():
net = nn.Sequential()
net.add(nn.Dense(1))
net.initialize()
return net
def log_error(net, features, labels):
# 将小于1的log值设成1
preds = nd.clip(net(features), 1, float('inf'))
error = nd.sqrt(2 * loss(preds.log(), labels.log()).mean())
return error.asscalar()
def train(net, train_features, train_labels, num_epochs, learning_rate, weight_decay, batch_size):
train_loss = []
train_iter = gdata.DataLoader(gdata.ArrayDataset(train_features, train_labels), batch_size=batch_size, shuffle=True)
#ADM优化算法 - 梯度下降改进
trainer = gluon.Trainer(net.collect_params(), 'adam', {'learning_rate' : learning_rate, 'wd' : weight_decay})
for epoch in range(num_epochs):
for data, label in train_iter:
# 自动求梯度
with autograd.record():
l = loss(net(data), label)
l.backward()
# 更新网络权重
trainer.update(batch_size) #or trainer.step(batch_size)
train_loss.append(log_error(net, train_features, train_labels))
return train_loss
def train_and_pred(train_features, train_labels, test_features, test_labels, num_epochs, learning_rate, weight_decay, batch_size):
net = get_net()
train_loss = train(net, train_features, train_labels, num_epochs, learning_rate, weight_decay, batch_size)
# d2lzh包画图
dd2l.semilogy(range(1, num_epochs + 1), train_loss, 'num_epoch', 'loss')
# 测试数据预测
preds = net(test_features).asnumpy()
test_data['SalePrice'] = preds.reshape((-1, 1))
submission = pd.concat([test_data['Id'], test_data['SalePrice']], axis=1)
# 写入预测结果
submission.to_csv('submission.csv', index=False)
# 超参数设置
num_epochs, learning_rate, weight_decay, batch_size = 100, 10, 0, 64
train_and_pred(train_features, train_labels, test_features, None, num_epochs, learning_rate, weight_decay, batch_size)