头歌 中国软件开源创新大赛培训答案有目录

中国软件开源创新大赛培训

深入Tensorflow

深度学习–循环神经网络

第1关 学习单步的RNN:RNNCell

# -*- 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 _ in range(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 in range(num_points):
        label[i] = 1 if np.prod(data[i]) < 0 else 0

    # 利用 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) in enumerate(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 in enumerate(mnist_train_dataloader):
        # 请在此添加代码 完成本关任务
        # ********** Begin *********#
        ##提示:batch_image, batch_label=
        batch_image, batch_label = batch_sample[0], batch_sample[1]
        # ********** End **********#

        # 中断
        break

    print(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 in enumerate(dataloader):
        batch_image, batch_label = batch_sample[0], batch_sample[1]
        break

    print("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 in range(num_points):
            self.label[i] = 1 if np.prod(self.data[i]) < 0 else 0

    # 定义获取数据集中每个样本的方法
    def __getitem__(self, index: int) -> Tuple:
        return self.data[index], self.label[index]

    # 定义返回数据集长度的方法
    def __len__(self) -> int:
        return len(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 = 2
        super().__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 in range(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 in range(num_points):
            self.label[i] = 1 if np.prod(self.data[i]) < 0 else 0

    # 定义获取数据集中每个样本的方法
    def __getitem__(self, index: int) -> Tuple:
        return self.data[index], self.label[index]

    # 定义返回数据集长度的方法
    def __len__(self) -> int:
        return len(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 = 2
        super().__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 in range(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 = 0
    for 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))


猜你喜欢

转载自blog.csdn.net/weixin_46263778/article/details/124002298
今日推荐