#-*- coding: utf-8-*-
import tensorflow as tf
# 参数 a 是 BasicRNNCell所含的神经元数, 参数 b 是 batch_size, 参数 c 是单个 input 的维数,shape =[ b , c ]
def creatRNNCell(a,b):# 请在此添加代码 完成本关任务
#********** Begin *********#
cell=tf.nn.rnn_cell.BasicRNNCell(num_units=a)
x1=tf.placeholder(tf.float32,[b,c])
h0=cell.zero_state(batch_size=b,dtype=tf.float32)
output,h1=cell.__call__(x1,h0)print(h1)#********** End **********#
第2关 探幽入微LSTM
#-*- coding: utf-8-*-
import tensorflow as tf
import numpy as np
# 参数 a 是 BasicLSTMCell所含的神经元数, 参数 b 是 batch_size, 参数 c 是单个 input 的维数,shape =[ b , c ]
def creatLSTMCell(a,b,c):# 请在此添加代码 完成本关任务
#********** Begin *********#
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units=a)
inputs = tf.placeholder(np.float32,[b,c])
h0 = lstm_cell.zero_state(batch_size=b,dtype=np.float32)
output, h1 = lstm_cell.__call__(inputs, h0)print(h1.h)print(h1.c)#********** End **********#
第3关 进阶RNN:学习一次执行多步以及堆叠RNN的构建
#-*- coding: utf-8-*-
import tensorflow as tf
import numpy as np
from tensorflow.contrib import rnn
# 参数 a 是RNN的层数, 参数 b 是每个BasicRNNCell包含的神经元数即state_size
# 参数 c 是输入序列的批量大小即batch_size,参数 d 是时间序列的步长即time_steps,参数 e 是单个输入input的维数即input_size
def MultiRNNCell_dynamic_call(a,b,c,d,e):# 用tf.nn.rnn_cell MultiRNNCell创建a层RNN,并调用tf.nn.dynamic_rnn
# 请在此添加代码 完成本关任务
#********** Begin *********#
cell = tf.nn.rnn_cell.MultiRNNCell([tf.nn.rnn_cell.BasicRNNCell(num_units=b)for _ inrange(a)])
inputs = tf.placeholder(np.float32, shape=(c, d,e))
h0 = cell.zero_state(c, tf.float32)
outputs, state = tf.nn.dynamic_rnn(cell, inputs, initial_state=h0)print(outputs)#********** End **********#
MegEngine 样例练习
天元 - 模型开发
第1关 基本概念
import numpy as np
import megengine as mge
import megengine.functional as F
def work():##张量概念实例
# 请在此添加代码完成本关任务
#**********Begin*********###提示(1) 补全代码 a : 定义一个维度为 (2,5) 的 ndarray,并转化成 MegEngine 的 Tensor
a = mge.tensor(np.random.random((2,5)).astype('float32'))##提示(2) 补全代码 b : 定义并初始化一个长度为3的列表,并转化成 Tensor
b = mge.tensor([1.,2.,3.])#**********End**********#print(a)print(b)
c = mge.tensor()# 此时 Tensor 尚未被初始化,值为 None
print(c)
c.set_value(np.random.random((2,5)).astype('float32'))# 此时我们将 Tensor c 进行了赋值
print(c)print(c.dtype)
d = c.astype("float16")print(d.dtype)print(c.shape)
a = mge.tensor(np.random.random((2,5)).astype('float32'))print(a)
b = a.numpy()print(b)##算子概念实例
# Tensor 的加法:
a = mge.tensor(np.random.random((2,5)).astype('float32'))print(a)
b = mge.tensor(np.random.random((2,5)).astype('float32'))print(b)print(a + b)# 请在此添加代码完成本关任务
#**********Begin*********###提示(1)补全代码:打印Tensor a 的切片
print(a[1,:])##提示(2)补全代码:Tensor a 形状的更改为(5,2)
a.reshape(5,2)#**********End**********#print(a.shape)#reshape() 的参数允许存在单个缺省值,用 -1 表示。此时,reshape 会自动推理该维度的值
# 原始维度是 (5,2),当给出 -1的缺省维度值时,可以推理出另一维度为10
a = a.reshape(1,-1)print(a.shape)# 创建的Tensor可以位于不同device,这根据当前的环境决定。通过 device 属性查询当前 Tensor 所在的设备。
print(a.device)##求导的操作方法
# 请在此添加代码完成本关任务
#**********Begin*********###提示(1):补全教程中算式的代码实现( x w b p m y)
x = mge.tensor(np.random.normal(size=(2,2)).astype('float32'))
w = mge.tensor(np.random.normal(size=(2,2)).astype('float32'))
b = mge.tensor(np.random.normal(size=(2,2)).astype('float32'))
p = x * w
m = p + b
y = m.sum()##提示(2):补全代码:求偏导
grad_w = F.grad(y, w, use_virtual_grad=False)#**********End**********#print(grad_w)print(grad_w.shape)
第2关 网络定义及运行
import megengine as mge
import megengine.functional as F
import numpy as np
import megengine.module as M
def work():##########练习1--使用 ReLU 作为激活函数,实现一个两层卷积网络########
def two_layer_conv(x):# 第一层
# 请在此添加代码完成本关任务
#**********Begin*********###(1)补全conv_weight的初始化:(8,3,3,3)<==>(输出信道数,输入信道数,卷积核高度,卷积核宽度)
##(2)补全conv_bias的初始化:(1,8,1,1) 对于 8 个卷积核,提供 8 个 bias
conv_weight = mge.Parameter(np.random.randn(8,3,3,3).astype(np.float32))
conv_bias = mge.Parameter(np.zeros((1,8,1,1), dtype=np.float32))#**********End**********#
x = F.conv2d(x, conv_weight, conv_bias)
x = F.relu(x)# 第二层
# 请在此添加代码完成本关任务
#**********Begin*********##(1)补全conv_weight的初始化:(16,8,3,3)<==>(输出信道数,输入信道数,卷积核高度,卷积核宽度)
#(2)补全conv_bias的初始化:(1,16,1,1) 对于 8 个卷积核,提供 8 个 bias
conv_weight = mge.Parameter(np.random.randn(16,8,3,3).astype(np.float32))
conv_bias = mge.Parameter(np.zeros((1,16,1,1), dtype=np.float32))#**********End**********#
x = F.conv2d(x, conv_weight, conv_bias)
x = F.relu(x)return x
# 输入形状为 (2,3,32,32) 的张量
x = mge.tensor(np.random.randn(2,3,32,32).astype(np.float32))
out =two_layer_conv(x)print(out.shape)###########练习2-基于 Module 搭建网络,简化练习1的网络搭建######### 为了练习,我们在这里定义了一个简单的卷积模块。注意: MegEngine 已经提供了更为通用的 Conv2d 模块。
class ConvReLU(M.Module):
def __init__(self, in_channels, out_channels):# 先调用父类的初始化
super().__init__()# 定义卷积权重和 bias ,作为模块参数
self.conv_weight = mge.Parameter(np.random.randn(out_channels, in_channels,3,3).astype(np.float32))
self.conv_bias = mge.Parameter(np.zeros((1, out_channels,1,1), dtype=np.float32))# 将激活函数 ReLU 作为子模块
self.relu = M.ReLU()
def forward(self, x):
x = F.conv2d(x, self.conv_weight, self.conv_bias)
x = self.relu(x)return x
# 基于 ConvReLU ,定义一个两层卷积网络
class TwoLayerConv(M.Module):
def __init__(self):super().__init__()# 请在此添加代码完成本关任务
#**********Begin*********###提示:补全代码:conv_relu1、conv_relu2的赋值(参数与练习1相同)
self.conv_relu1 =ConvReLU(3,8)
self.conv_relu2 =ConvReLU(8,16)#**********End**********#
def forward(self, x):
x = self.conv_relu1(x)
x = self.conv_relu2(x)return x
# 输入形状为 (2,3,32,32) 的张量
x = mge.tensor(np.random.randn(2,3,32,32).astype(np.float32))
two_layer_conv_module =TwoLayerConv()
out =two_layer_conv_module(x)print(out.shape)# 输出: (2,16,28,28)
第3关 基于module搭建LeNet网络
import megengine as mge
import megengine.functional as F
import numpy as np
import megengine.module as M
def work():#########练习3-搭建更加复杂的、经典的 LeNet网络#############
class LeNet(M.Module):
def __init__(self):super(LeNet, self).__init__()# 单信道图片, 两层 5x5 卷积 + ReLU + 池化
self.conv1 = M.Conv2d(1,6,5)
self.relu1 = M.ReLU()
self.pool1 = M.MaxPool2d(2,2)
self.conv2 = M.Conv2d(6,16,5)
self.relu2 = M.ReLU()
self.pool2 = M.MaxPool2d(2,2)# 两层全连接 + ReLU
self.fc1 = M.Linear(16*5*5,120)
self.relu3 = M.ReLU()
self.fc2 = M.Linear(120,84)
self.relu4 = M.ReLU()# 分类器
self.classifer = M.Linear(84,10)
def forward(self, x):# 请在此添加代码完成本关任务
#**********Begin*********###提示:补全forward函数,求得x
x = self.pool1(self.relu1(self.conv1(x)))
x = self.pool2(self.relu2(self.conv2(x)))# F.flatten 将原本形状为 (N, C, H, W) 的张量x从第一个维度(即C)开始拉平成一个维度,
# 得到的新张量形状为 (N, C*H*W) 。 等价于 reshape 操作: x = x.reshape(x.shape[0],-1)
x = F.flatten(x,1)
x = self.relu3(self.fc1(x))
x = self.relu4(self.fc2(x))
x = self.classifer(x)#**********End**********#return x
# 输入形状为 (2,1,32,32) 的张量
x = mge.tensor(np.random.randn(2,1,32,32).astype(np.float32))
le_net =LeNet()# 调用网络,即执行 le_net 的 forward 成员方法,返回网络处理结果
out =le_net(x)print(out.shape)# 输出: (2,10)
天元 - 模型开发
第1关 数据加载
from megengine.data.dataset import ArrayDataset
import numpy as np
from typing import Tuple
from megengine.data import SequentialSampler
from megengine.data import DataLoader
def train():# 准备 NumPy 形式的 data 和 label 数据
np.random.seed(2020)
num_points =30000
data = np.random.rand(num_points,2).astype(np.float32)*2-1
label = np.zeros(num_points, dtype=np.int32)for i inrange(num_points):
label[i]=1if np.prod(data[i])<0else0# 利用 ArrayDataset 创建一个数据集类
xor_dataset =ArrayDataset(data, label)#********** Begin *********###提示:使用随机采样器SequentialSampler 初始化batch_size=4,dataset=xor_dataset的采样器sequential_sampler
sequential_sampler =SequentialSampler(dataset=xor_dataset, batch_size=4)#********** End **********## 获取迭代sampler时每次返回的数据集索引
for indices in sequential_sampler:print(indices)break#********** Begin *********###提示:使用DataLoader初始化一个采样方式为随机采样、dataset=xor_dataset的批数据
xor_dataloader =DataLoader(dataset=xor_dataset,sampler=sequential_sampler,)#********** End **********#print("The length of the xor_dataloader is: {}".format(len(xor_dataloader)))# 从 DataLoader 中迭代地获取每批数据
for idx,(cor, tag)inenumerate(xor_dataloader):print("iter %d : "%(idx), cor, tag)break;
第2关 数据变换
from megengine.data.dataset import MNIST
from megengine.data import SequentialSampler
from megengine.data import DataLoader
import matplotlib.pyplot as plt
from megengine.data.transform import RandomResizedCrop, Normalize, ToMode, Pad, Compose
def transform():# 若你是一次下载 MNIST 数据集,download 需设置成 True
# 若你已经下载 MNIST 数据集,通过 root 指定 MNIST 数据集 raw 路径
# 通过设置 train=True/False 获取训练集或测试集
mnist_train_dataset =MNIST(root="MegEngine/step2/dataset/MNIST", train=True, download=False)
sequential_sampler =SequentialSampler(dataset=mnist_train_dataset, batch_size=4)
mnist_train_dataloader =DataLoader(
dataset=mnist_train_dataset,
sampler=sequential_sampler,)for i, batch_sample inenumerate(mnist_train_dataloader):# 请在此添加代码 完成本关任务
#********** Begin *********###提示:batch_image, batch_label=
batch_image, batch_label = batch_sample[0], batch_sample[1]#********** End **********## 中断
breakprint(batch_image.shape)####组合转换的练习
dataloader =DataLoader(
mnist_train_dataset,
sampler=sequential_sampler,# 请在此添加代码 完成本关任务
#********** Begin *********## 提示:补全Compose([]):利用 ``Compose`` 组合多个 Transform 操作
##Compose参数:
##RandomResizedCrop : output_size=28##Normalize: mean=0.1307*255, std=0.3081*255##Pad :2##ToMode:'CHW'
transform=Compose([RandomResizedCrop(output_size=28),Normalize(mean=0.1307*255, std=0.3081*255),Pad(2),ToMode('CHW'),])#********** End **********#)for i, batch_sample inenumerate(dataloader):
batch_image, batch_label = batch_sample[0], batch_sample[1]breakprint("The shape of the batch is now: {}".format(batch_image.shape))
第3关 网络训练与保存
import numpy as np
from typing import Tuple
from megengine.data.dataset import Dataset
from megengine.data import DataLoader
import megengine.module as M
import megengine.functional as F
from megengine.data.sampler import RandomSampler
from megengine.jit import trace
import megengine.optimizer as optim
import megengine as mge
######第一步 数据准备
class XORDataset(Dataset):
def __init__(self, num_points):super().__init__()# 初始化一个维度为 (num_points,2) 的 NumPy 数组,
# 该数组的每一行数据为可以看为一个横坐标和纵坐标都落在 [-1,1] 区间的一个数据点 (x, y)
self.data = np.random.rand(num_points,2).astype(np.float32)*2-1# 为上述 NumPy 数组构建标签,每一行的 (x, y) 如果符合 x*y <0,则对应标签为1,反之,标签为0
self.label = np.zeros(num_points, dtype=np.int32)for i inrange(num_points):
self.label[i]=1if np.prod(self.data[i])<0else0# 定义获取数据集中每个样本的方法
def __getitem__(self, index: int)-> Tuple:return self.data[index], self.label[index]# 定义返回数据集长度的方法
def __len__(self)-> int:returnlen(self.data)
np.random.seed(2020)# 固定随机种子,保证数据生成可复现
train_dataset =XORDataset(30000)
test_dataset =XORDataset(10000)#####第二步 模型搭建
class XORNet(M.Module):
def __init__(self):
self.mid_dim =14
self.num_class =2super().__init__()
self.fc0 = M.Linear(self.num_class, self.mid_dim, bias=True)
self.fc1 = M.Linear(self.mid_dim, self.mid_dim, bias=True)
self.fc2 = M.Linear(self.mid_dim, self.num_class, bias=True)
def forward(self, x):
x = self.fc0(x)
x = F.tanh(x)
x = self.fc1(x)
x = F.tanh(x)
x = self.fc2(x)return x
xor_net =XORNet()######第三步 模型训练与保存
#1、创建 DataLoader 用于训练:
batch_size =100
sampler =RandomSampler(dataset=train_dataset, batch_size=batch_size)#请在此添加代码完成本关任务
#**********Begin*********###提示:补全代码train_dataloader =DataLoader()
train_dataloader =DataLoader(train_dataset,sampler=sampler,)#**********End**********##2、定义静态图训练函数
@trace(symbolic=True)
def train_func(data, label,*, net, optimizer):
net.train()# 网络设置成训练模式
pred =net(data)# 请在此添加代码完成本关任务
#**********Begin*********###提示:补全代码loss(使用交叉熵损失)
loss = F.cross_entropy_with_softmax(pred, label)#**********End**********#
optimizer.backward(loss)return pred, loss
#3、定义优化器
#请在此添加代码完成本关任务
#**********Begin*********###提示:补全代码opt = optim.SGD() 考虑参数lr和momentum
opt = optim.SGD(xor_net.parameters(), lr=0.01, momentum=0.9)#**********End**********##4、训练迭代,优化器更新参数
def train():
epochs =5
data_tensor = mge.tensor()
label_tensor = mge.tensor(dtype=np.int32)for i inrange(epochs):
loss_rec =[]for data, label in train_dataloader:
data_tensor.set_value(data)
label_tensor.set_value(label)
opt.zero_grad()# 请在此添加代码完成本关任务
#**********Begin*********###提示:补全代码pred, loss=train_func()
pred, loss =train_func(data, label, net=xor_net, optimizer=opt)#**********End**********#
opt.step()
loss_rec.append(loss.numpy().item())# 请在此添加代码完成本关任务
#**********Begin*********###提示:补全代码,计算每轮次loss值
loss =sum(loss_rec)/len(loss_rec)#**********End**********#print("[Epoch {}] loss: {}".format(i, loss))###网络保存
mge.save(xor_net.state_dict(),'xor_net.mge')print("ok")
第4关 网络的加载与测试
import numpy as np
from typing import Tuple
from megengine.data.dataset import Dataset
from megengine.data import DataLoader
import megengine.module as M
import megengine.functional as F
from megengine.data.sampler import RandomSampler
from megengine.jit import trace
import megengine.optimizer as optim
import megengine as mge
from megengine.data.sampler import SequentialSampler
######前半部分是上一关卡的网络训练与保存,本次关卡的练习在work函数中##############第一步 数据准备
class XORDataset(Dataset):
def __init__(self, num_points):super().__init__()# 初始化一个维度为 (num_points,2) 的 NumPy 数组,
# 该数组的每一行数据为可以看为一个横坐标和纵坐标都落在 [-1,1] 区间的一个数据点 (x, y)
self.data = np.random.rand(num_points,2).astype(np.float32)*2-1# 为上述 NumPy 数组构建标签,每一行的 (x, y) 如果符合 x*y <0,则对应标签为1,反之,标签为0
self.label = np.zeros(num_points, dtype=np.int32)for i inrange(num_points):
self.label[i]=1if np.prod(self.data[i])<0else0# 定义获取数据集中每个样本的方法
def __getitem__(self, index: int)-> Tuple:return self.data[index], self.label[index]# 定义返回数据集长度的方法
def __len__(self)-> int:returnlen(self.data)
np.random.seed(2020)# 固定随机种子,保证数据生成可复现
train_dataset =XORDataset(30000)
test_dataset =XORDataset(10000)#####第二步 模型搭建
class XORNet(M.Module):
def __init__(self):
self.mid_dim =14
self.num_class =2super().__init__()
self.fc0 = M.Linear(self.num_class, self.mid_dim, bias=True)
self.fc1 = M.Linear(self.mid_dim, self.mid_dim, bias=True)
self.fc2 = M.Linear(self.mid_dim, self.num_class, bias=True)
def forward(self, x):
x = self.fc0(x)
x = F.tanh(x)
x = self.fc1(x)
x = F.tanh(x)
x = self.fc2(x)return x
xor_net =XORNet()######第三步 模型训练与保存
#1、创建 DataLoader 用于训练:
batch_size =100
sampler =RandomSampler(dataset=train_dataset, batch_size=batch_size)
train_dataloader =DataLoader(
train_dataset,
sampler=sampler,)#2、定义静态图训练函数
@trace(symbolic=True)
def train_func(data, label,*, net, optimizer):
net.train()# 网络设置成训练模式
pred =net(data)# 使用交叉熵损失
loss = F.cross_entropy_with_softmax(pred, label)
optimizer.backward(loss)return pred, loss
#3、定义优化器
opt = optim.SGD(xor_net.parameters(), lr=0.01, momentum=0.9)#4、训练迭代,优化器更新参数
# 训练迭代,优化器更新参数
epochs =5
data_tensor = mge.tensor()
label_tensor = mge.tensor(dtype=np.int32)for i inrange(epochs):
loss_rec =[]for data, label in train_dataloader:
data_tensor.set_value(data)
label_tensor.set_value(label)
opt.zero_grad()
_, loss =train_func(data, label, net=xor_net, optimizer=opt)
opt.step()
loss_rec.append(loss.numpy().item())
loss =sum(loss_rec)/len(loss_rec)print("[Epoch {}] loss: {}".format(i, loss))
mge.save(xor_net.state_dict(),'xor_net.mge')
def work():# 对于测试程序,首先加载训练好的模型:
xor_net =XORNet()
state_dict = mge.load('xor_net.mge')
xor_net.load_state_dict(state_dict)# 创建 DataLoader 用于测试:
sampler =SequentialSampler(test_dataset, batch_size=100)
test_dataloader =DataLoader(
test_dataset,
sampler=sampler
)# 定义静态图测试函数
@trace(symbolic=True)
def eval_func(data, label,*, net):
net.eval()# 网络设置为测试模式
pred =net(data)# 请在此添加代码完成本关任务
#**********Begin*********###提示:补全代码loss=
loss = F.cross_entropy_with_softmax(pred, label)#**********End**********#return pred, loss
correct =0
total =0for data, label in test_dataloader:# 请在此添加代码完成本关任务
#**********Begin*********###提示:补全代码,完成测试
pred, _ =eval_func(data, label, net=xor_net)
pred_label = pred.numpy().argmax(axis=1)
correct +=(pred_label == label).sum().item()
total += label.shape[0]#**********End**********#print("correct: {}, total: {}, accuracy: {:.2f}%".format(correct, total, correct *100.0/ total))