Datawhale:动手深度学习第一次打卡!

不羁的心 提交于 2020-02-15 09:46:34

Datawhale:动手深度学习第一次打卡!

这几天将视频中的代码重新敲了一边,感觉自己学到了不少东西:

  • 编程一定要多练呀!!!(叫破喉咙)
  • 要多看看一些写的好的代码,不然你就不知道自己代码写的有多辣眼睛
  • 学习了一些python的语法点已经一些小技巧
  • 又再次复习了以下知识点

Task01:

线性回归

import torch
from torch import nn
import numpy as np

torch.manual_seed(1)

print(torch.__version__)
torch.set_default_tensor_type('torch.FloatTensor')

# 生成数据
num_inputs = 2
num_examples = 1000

true_w = [2, -3.4]
true_b = 4.2

features = torch.tensor(np.random.normal(0, 1, (num_examples, num_inputs)), dtype=torch.float)
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)

# 读取数据
import torch.utils.data as Data
batch_size = 10


dataset = Data.TensorDataset(features, labels)

data_iter = Data.DataLoader(
    dataset=dataset,            # torch TensorDataset format
    batch_size=batch_size,      # mini batch size
    shuffle=True,               # whether shuffle the data or not
)

for X, y in data_iter:
    print(X, '\n', y)
    break


# 定义模型
net = nn.Sequential(
    nn.Linear(num_inputs, 1)
    )


# 初始化模型参数

from torch.nn import init

init.normal_(net[0].weight, mean=0.0, std=0.01)
init.constant_(net[0].bias, val=0.0) 

for param in net.parameters():
    print(param)

# 定义损失函数
loss = nn.MSELoss()

# 定义优化函数
import torch.optim as optim

optimizer = optim.SGD(net.parameters(), lr=0.03)   # built-in random gradient descent function
print(optimizer)  # function prototype: `torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)`


# 训练
num_epochs = 3
for epoch in range(1, num_epochs + 1):
    for X, y in data_iter:
        output = net(X)
        l = loss(output, y.view(-1, 1))
        optimizer.zero_grad() # reset gradient, equal to net.zero_grad()
        l.backward()
        optimizer.step()
    print('epoch %d, loss: %f' % (epoch, l.item()))

dense = net[0]
print(true_w, dense.weight.data)
print(true_b, dense.bias.data)

Softmax与多分类

from IPython import  display
import matplotlib.pyplot as plt

import torch
import torchvision
import numpy as np

import torchvision.transforms as transforms
import time

import sys
import d2lzh_pytorch as d21

# 读入数据
dataRootPath = r"E:\data\torchvision\FashionMNIST"
mnist_train = torchvision.datasets.FashionMNIST(root=dataRootPath,
                                                train=True, download=True, transform=transforms.ToTensor())
mnist_test = torchvision.datasets.FashionMNIST(root=dataRootPath,
                                               train=False, download=True, transform=transforms.ToTensor())

# 展示数据
def show_fashion_mnist(images, labels):
    d21.use_svg_display()
    _, figs = plt.subplots(1, len(images), figsize=(12, 12))
    for f, img, lbl in zip(figs, images, labels):
        f.imshow(img.view((28, 28)).numpy())
        f.set_title(lbl)
        f.axes.get_xaxis().set_visible(False)
        f.axes.get_yaxis().set_visible(False)
    plt.show()

X, y = [], []
for i in range(10):
    X.append(mnist_train[i][0])
    y.append(mnist_train[i][1])

show_fashion_mnist(X, d21.get_fashion_mnist_labels(y))

# 读取数据

batch_size = 256
train_iter, test_iter = d21.load_data_fashion_mnist(batch_size)

num_inputs = 784
num_outputs = 10


# 定义并初始化参数
W = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_outputs)), dtype=torch.float)
b = torch.zeros(num_outputs, dtype=torch.float)

W.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)


# 定义softmax函数
def softmax(X):
    X_exp = X.exp()
    partition = X_exp.sum(dim=1, keepdim=True)
    return X_exp / partition


# 定义模型
def net(X):
    return softmax(torch.mm(X.view((-1, num_inputs)), W) + b)

# 定义损失函数
def cross_entropy(y_hat, y):
    return - torch.log(y_hat.gather(1, y.view(-1, 1)))

# 定义评估函数
def accuracy(y_hat, y):
    return (y_hat.argmax(dim=1) == y).float().mean().item()


# 训练
num_epochs, lr = 5, 0.1

def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,
              params=None, lr=None, optimizer=None):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0

        for X, y in train_iter:
            y_hat = net(X)
            l = loss(y_hat, y).sum()

            if optimizer is not  None:
                optimizer.zero_grad()
            elif params is not  None and params[0].grad is not None:
                for param in params:
                    param.grad.data.zero_()

            l.backward()
            if optimizer is None:
                d21.sgd(params, lr, batch_size)
            else:
                optimizer.step()

            train_l_sum += l.item()
            train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()

            n += y.shape[0]

        test_acc = d21.evaluate_accuracy(test_iter, net)
        print("epoch: {0}, loss:{1:.4f}, train acc: {2:.3f}, test acc{3:.3f}"
              .format(epoch+1, train_l_sum/n, train_acc_sum/n, test_acc))

train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [W, b], lr)

多层感知机

import torch
import numpy as np

import d2lzh_pytorch as d2l

dataRootPath = r"E:\data\torchvision\FashionMNIST"

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size,
                                                    root=dataRootPath)

num_inputs, num_outputs, num_hiddens = 784, 10, 256

W1 = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_hiddens)), dtype=torch.float)
b1 = torch.zeros(num_hiddens, dtype=torch.float)
W2 = torch.tensor(np.random.normal(0, 0.01, (num_hiddens, num_outputs)), dtype=torch.float)
b2 = torch.zeros(num_outputs, dtype=torch.float)

params = [W1, b1, W2, b2]
for param in params:
    param.requires_grad_(requires_grad=True)

def relu(X):
    return torch.max(input=X, other=torch.tensor(0.0))

def net(X):
    X = X.view(-1, num_inputs)
    H = relu(torch.matmul(X, W1) + b1)
    return torch.matmul(H, W2) + b2

loss = torch.nn.CrossEntropyLoss()

num_epochs, lr = 5, 0.01
def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,
              params=None, lr=None, optimizer=None):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
        for X, y in train_iter:
            y_hat = net(X)
            l = loss(y_hat, y).sum()

            if optimizer is not None:
                optimizer.zero_grad()
            elif params is not None and params[0].grad is not None:
                for param in params:
                    param.grad.data.zero_()

            l.backward()
            if optimizer is None:
                d2l.sgd(params, lr, batch_size)
            else:
                optimizer.step()

            train_l_sum += l.item()
            train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()
            n += y.shape[0]
        test_acc = d2l.evaluate_accuracy(test_iter, net)
        print("epoch: {0}, loss:{1:.4f}, train acc: {2:.3f}, test acc: {3:.3f}"
              .format(epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))

train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)

Task02:

文本预处理

主要介绍了如何从文本词的序列转化为索引的序列

import  collections
import re

# 读入文本
def read_time_machine():
    fname = r'./data/timemachine.txt'
    with open(fname, 'r') as f:
        lines = [re.sub('[^a-z]+', ' ', line.strip()) for line in f]
    return lines

lines = read_time_machine()

def tokenize(sentences, token='word'):
    if token == 'word':
        return [sentence.split(' ') for sentence in sentences]
    elif token == 'char':
        return [list(sentence) for sentence in sentences]
    else:
        print('ERROR: unknown token type '+token)

tokens = tokenize(lines)

def count_corpus(sentences):
    tokens = [tk for st in sentences for tk in st]
    return collections.Counter(tokens)


class Vocab(object):
    def __init__(self, tokens, min_freq=0, use_special_tokens=False):
        counter = count_corpus(tokens)
        self.token_freqs = list(counter.items())
        self.idx_to_token = []
        if use_special_tokens:
            self.pad, self.bos, self.eos, self.unk = (0, 1, 2, 3)
            self.idx_to_token += ['', '', '', '']
        else:
            self.unk = 0
            self.idx_to_token += ['']

        self.idx_to_token += [token for token, freq in self.token_freqs
                              if freq >= min_freq and token not in self.idx_to_token]
        self.token_to_idx = dict()
        for idx, token in enumerate(self.idx_to_token):
            self.token_to_idx[token] = idx

    def __len__(self):
        return len(self.idx_to_token)

    def __getitem__(self, tokens):
        if not isinstance(tokens, (list, tuple)):
            return self.token_to_idx.get(tokens, self.unk)
        return [self.__getitem__(token) for token in tokens]

    def to_tokens(self, indices):
        if not isinstance(indices, (list, tuple)):
            return self.idx_to_token[indices]
        return [self.idx_to_token[index] for index in indices]


vocab = Vocab(tokens)
print(list(vocab.token_to_idx.items()))

text = "Mr. Chen doesn't agree with my suggestion."

import spacy
nlp = spacy.load('en_core_web_sm')
doc = nlp(text)
print([token.text for token in doc])

from nltk.tokenize import word_tokenize
from nltk import data
print(word_tokenize(text))

语言模型

主要介绍了如何对时间序列进行采样


def load_data_jay_lyrics():
    fname = "./data/jaychou_lyrics.txt"
    with open(fname, 'r', encoding='utf-8') as f:
        corpus_chars = f.read()

    corpus_chars = corpus_chars.replace('\n', ' ').replace('\r', ' ')
    corpus_chars = corpus_chars[0:10000]
    idx_to_char = list(set(corpus_chars))
    char_to_idx = dict([(char, i) for i, char in enumerate(idx_to_char)])
    vocab_size = len(char_to_idx)
    corpus_indices = [char_to_idx[char] for char in corpus_chars]
    return corpus_indices, char_to_idx, idx_to_char, vocab_size


import torch
import random

# 随机采样
def data_iter_random(corpus_indices, batch_size, num_steps, device=None):
    num_examples = (len(corpus_indices) - 1) // num_steps
    example_indices = [i*num_steps for i in range(num_examples)]

    random.shuffle(example_indices)

    def _data(i):
        return corpus_indices[i:i+num_steps]

    if device is None:
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    for i in range(0, num_examples, batch_size):
        batch_indices = example_indices[i:i+batch_size]
        X = [_data(j) for j in batch_indices]
        Y = [_data(j+1) for j in batch_indices]
        yield torch.tensor(X, device=device), torch.tensor(Y, device=device)

my_seq = list(range(30))
for X, Y in data_iter_random(my_seq, batch_size=2, num_steps=6):
    print('X: ', X, '\nY: ', Y, '\n')

# 相邻采样
def data_iter_consecutive(corpus_indices, batch_size, num_steps, device=None):
    if device is None:
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    corpus_len = len(corpus_indices) // batch_size * batch_size
    corpus_indices = corpus_indices[:corpus_len]
    indices = torch.tensor(corpus_indices, device=device)
    indices = indices.view(batch_size, -1)

    batch_num = (indices.shape[1] - 1) // num_steps
    for i in range(batch_num):
        i = i * num_steps
        X = indices[:, i:i+num_steps]
        Y = indices[:, i+1:i+num_steps+1]
        yield X, Y

my_seq = list(range(29))
print(my_seq)
for X, Y in data_iter_random(my_seq, batch_size=3, num_steps=6  ):
    print('X: ', X, '\nY: ', Y, '\n')


循环神经网络基础

这一部分还没看完,等看完了再来补充哈

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!