Pytorch基础——使用 RNN 生成简单序列

一、介绍

内容

使用 RNN 进行序列预测

今天我们就从一个基本的使用 RNN 生成简单序列的例子中,来窥探神经网络生成符号序列的秘密。

我们首先让神经网络模型学习形如 0^n 1^n 形式的上下文无关语法。然后再让模型尝试去生成这样的字符串。在流程中将演示 RNN 及 LSTM 相关函数的使用方法。

实验知识点

  • 什么是上下文无关文法
  • 使用 RNN 或 LSTM 模型生成简单序列的方法
  • 探究 RNN 记忆功能的内部原理

二、什么是上下文无关语法

上下文无关语法

首先让我们观察以下序列:

  • 01
  • 0011
  • 000111
  • 00001111
  • ……

它们有什么特点和规律呢?

它们都只含有 0 和 1 并连续地出现,序列长度并不相等,但在每条序列中 0 和 1 的个数是相等的。我们可以用一个简单的数学表达式来表述所有这些 01 序列的通用规律,其实就是 0^n 1^n,其中 n 就是序列中 0 或者 1 的个数。这样的序列看似简单,但其实它在计算机科学中有一个非常响亮的名字,叫做“上下文无关文法”(Context-free grammar)。所谓上下文无关文法,简单来说,就是可以被一组替代规则所生成,而与本身所处的上下文(前后出现的字符)无关。

上下文无关语法序列的生成

针对上面这种 0^n 1^n 形式的上下文无关语法序列,我们人类要学会数出 0 的个数 n,这样也就自然知道了 1 的个数。可问题的难点是,对于一个机器来说,它必须自己学习出如何数 0 的个数,而不能从任何其它的途径获取 n。这个问题对于人类来说很容易,并且对于一个特定编写的程序来说也很简单。但是对于一个通用的神经网络模型来说,这就并不容易了,因为它自身并不会长出来一个计数器。它必须通过观察数据归纳总结,发明一种记忆系统从而能够看出 0 和 1 之间的长程规律,并实现等价的计数功能。尤其是当 n 很大的时候,这个问题将非常困难。因为序列越长,模型对记忆系统的要求就越高。大致了解了思路和关键问题后,下面就让我们来看看如何用 RNN 来解决这个问题。

三、使用 RNN 模型进行序列生成

引入相关包

值得注意的是本次使用了 Counter 搜集器,它可以让统计词频变得更简单。

# 导入程序所需要的程序包

#PyTorch用的包
import torch
import torch.nn as nn
import torch.optim
from torch.autograd import Variable

from collections import Counter #搜集器,可以让统计词频更简单

#绘图、计算用的程序包
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import rc
import numpy as np
#将图形直接显示出来
%matplotlib inline

生成训练数据

为了让训练能够有更好的效果,生成时故意将字符串的长度控制的比较短。为了让模型可以意识到每个字符串的起始与结束,每个序列中除了 0、1 以外,还有 3、2。其中 3 代表字符串的起始,2 代表字符串的结束。所有字符串都是如下的形式:30001112,300112,3012...

那么下面首先设定控制生成字符串长度的概率。

# 生成的样本数量
samples = 2000

# 训练样本中n的最大值
sz = 10
# 定义不同n的权重,我们按照10:6:4:3:1:1...来配置字符串生成中的n=1,2,3,4,5,...
probability = 1.0 * np.array([10, 6, 4, 3, 1, 1, 1, 1, 1, 1])
# 保证n的最大值为sz
probability = probability[ : sz]
# 归一化,将权重变成概率
probability = probability / sum(probability)
train_set = []

# 开始生成samples这么多个样本
for m in range(samples):
    # 对于每一个生成的字符串,随机选择一个n,n被选择的权重被记录在probability中
    n = np.random.choice(range(1, sz + 1), p = probability)
    # 生成这个字符串,用list的形式完成记录
    inputs = [0] * n + [1] * n
    # 在最前面插入3表示起始字符,2插入尾端表示终止字符
    inputs.insert(0, 3)
    inputs.append(2)
    train_set.append(inputs) #将生成的字符串加入到train_set训练集中

在生成训练数据的同时,也将校验数据集生成,并保存到 valid_set 中。

valid_set = []

# 再生成samples/10的校验样本
for m in range(samples // 10):
    n = np.random.choice(range(1, sz + 1), p = probability)
    inputs = [0] * n + [1] * n
    inputs.insert(0, 3)
    inputs.append(2)
    valid_set.append(inputs)

与训练数据集不同的是,我们会生成少量的超长序列,也就是 n 超大的序列在校验数据集中,用以考验模型的能力极限。

# 再生成若干n超大的校验样本
for m in range(2):
    n = sz + m
    inputs = [0] * n + [1] * n
    inputs.insert(0, 3)
    inputs.append(2)
    valid_set.append(inputs)
np.random.shuffle(valid_set)

定义 RNN 模型

PyTorch 提供了丰富的常用模型调用,所以我们无需去实现 RNN 模型的结构,直接调用函数即可。

正因为有了 RNN 函数,定义本次实验中 RNN 模型的方法与之前定义模型一样简单。

# 实现一个简单的RNN模型
class SimpleRNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, num_layers = 1):
        # 定义
        super(SimpleRNN, self).__init__()

        self.hidden_size = hidden_size
        self.num_layers = num_layers
        # 一个embedding层
        self.embedding = nn.Embedding(input_size, hidden_size)
        # PyTorch的RNN层,batch_first标志可以让输入的张量的第一个维度表示batch指标
        self.rnn = nn.RNN(hidden_size, hidden_size, num_layers, batch_first = True)
        # 输出的全链接层
        self.fc = nn.Linear(hidden_size, output_size)
        # 最后的logsoftmax层
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, input, hidden):
        # 运算过程
        # 先进行embedding层的计算,它可以把一个数值先转化为one-hot向量,再把这个向量转化为一个hidden_size维的向量
        # input的尺寸为:batch_size, num_step, data_dim
        x = self.embedding(input)
        # 从输入到隐含层的计算
        # x的尺寸为:batch_size, num_step, hidden_size
        output, hidden = self.rnn(x, hidden)
        # 从输出output中取出最后一个时间步的数值,注意output输出包含了所有时间步的结果,
        # output输出尺寸为:batch_size, num_step, hidden_size
        output = output[:,-1,:]
        # output尺寸为:batch_size, hidden_size
        # 喂入最后一层全链接网络
        output = self.fc(output)
        # output尺寸为:batch_size, output_size
        # softmax函数
        output = self.softmax(output)
        return output, hidden

    def initHidden(self):
        # 对隐含单元的初始化
        # 注意尺寸是: layer_size, batch_size, hidden_size
        return Variable(torch.zeros(self.num_layers, 1, self.hidden_size))

我们将上面代码的某些语句单独拿出来讲一下,首先:

self.embedding = nn.Embedding(input_size, hidden_size)

即输入首先会经过嵌入层被“压缩”至 hidden_size 的尺寸。这里嵌入层起到的作用与之前的实验相同,所以就不细讲了。值得一提的是 nn.RNN 这个部件,也就是所谓的 RNN 函数。

self.rnn = nn.RNN(hidden_size, hidden_size, num_layers, batch_first = True)

在定义这个部件的时候,需要指定输入给 RNN 层的向量尺寸 input_size(这里为输入经过嵌入后的 hidder_size)。以及 RNN 层隐含节点的数量 hidden_size,还包括 RNN 层的层数 num_layers

最后的参数 batch_first 管理了一个与用户编程习惯有关系的小细节。当把它设置为 True 的时候,RNN 输入变量的第一个维度就是批数据(batch)的维度,这与我们使用其它函数的习惯是一样的。

否则的话,按照 nn.RNN 的默认处理情况,批的维度在第二个位置上,而把第一个维度留给了时间。

训练 RNN 模型

首先实例化模型,定义模型的损失函数与优化算法

# 生成一个最简化的RNN,输入size为4,可能值为0,1,2,3,输出size为3,可能值为0,1,2
rnn = SimpleRNN(input_size = 4, hidden_size = 2, output_size = 3)
criterion = torch.nn.NLLLoss() #交叉熵损失函数
optimizer = torch.optim.Adam(rnn.parameters(), lr = 0.001) #Adam优化算法

然后是训练函数。

train_loss = 0

def trainRNN(epoch):
    global train_loss
    train_loss = 0
    # 对train_set中的数据进行随机洗牌,以保证每个epoch得到的训练顺序都不一样。
    np.random.shuffle(train_set)
    # 对train_set中的数据进行循环
    for i, seq in enumerate(train_set):
        loss = 0
        hidden = rnn.initHidden()  #初始化隐含层神经元
        # 对每一个序列的所有字符进行循环
        for t in range(len(seq) - 1):
            #当前字符作为输入,下一个字符作为标签
            x = Variable(torch.LongTensor([seq[t]]).unsqueeze(0))
            # x尺寸:batch_size = 1, time_steps = 1, data_dimension = 1
            y = Variable(torch.LongTensor([seq[t + 1]]))
            # y尺寸:batch_size = 1, data_dimension = 1
            output, hidden = rnn(x, hidden) #RNN输出
            # output尺寸:batch_size, output_size = 3
            # hidden尺寸:layer_size =1, batch_size=1, hidden_size
            loss += criterion(output, y) #计算损失函数
        loss = 1.0 * loss / len(seq) #计算每字符的损失数值
        optimizer.zero_grad() # 梯度清空
        loss.backward() #反向传播,设置retain_variables
        optimizer.step() #一步梯度下降
        train_loss += loss #累积损失函数值
        # 把结果打印出来
        if i > 0 and i % 500 == 0:
            print('第{}轮, 第{}个,训练Loss:{:.2f}'.format(epoch,
                                                    i,
                                                    train_loss.data.numpy() / i
                                                   ))

验证函数

valid_loss = 0
errors = 0
show_out = ''

def evaluateRNN():
    global valid_loss
    global errors
    global show_out
    valid_loss = 0
    errors = 0
    show_out = ''
    for i, seq in enumerate(valid_set):
        # 对每一个valid_set中的字符串做循环
        loss = 0
        outstring = ''
        targets = ''
        diff = 0
        hidden = rnn.initHidden() #初始化隐含层神经元
        for t in range(len(seq) - 1):
            # 对每一个字符做循环
            x = Variable(torch.LongTensor([seq[t]]).unsqueeze(0))
            # x尺寸:batch_size = 1, time_steps = 1, data_dimension = 1
            y = Variable(torch.LongTensor([seq[t + 1]]))
            # y尺寸:batch_size = 1, data_dimension = 1
            output, hidden = rnn(x, hidden)
            # output尺寸:batch_size, output_size = 3
            # hidden尺寸:layer_size =1, batch_size=1, hidden_size
            mm = torch.max(output, 1)[1][0] #以概率最大的元素作为输出
            outstring += str(mm.data.numpy()) #合成预测的字符串
            targets += str(y.data.numpy()[0]) #合成目标字符串
            loss += criterion(output, y) #计算损失函数

            diff += 1 - mm.eq(y).data.numpy()[0] #计算模型输出字符串与目标字符串之间差异的字符数量
        loss = 1.0 * loss / len(seq)
        valid_loss += loss #累积损失函数值
        errors += diff #计算累积错误数
        if np.random.rand() < 0.1:
            #以0.1概率记录一个输出字符串
            show_out = outstring + '\n' + targets
    # 打印结果
    print(output[0][2].data.numpy())

在下面的训练代码中实际上进行了三重循环,Epoch 作为第一重循环,然后在 trainRNN 中对每个 train_set 中的字符串做第二重循环,最后是对每一个字符串中的每一个字符做循环。

#重复进行20次试验
num_epoch = 20
results = []
for epoch in range(num_epoch):
    # 调用训练函数
    trainRNN(epoch)

    # 在校验集上测试
    evaluateRNN()

    # 打印结果
    print('第{}轮, 训练Loss:{:.2f}, 校验Loss:{:.2f}, 错误率:{:.2f}'.format(epoch,
                                                               train_loss.data.numpy() / len(train_set),
                                                               valid_loss.data.numpy() / len(valid_set),
                                                               1.0 * errors / len(valid_set)
                                                              ))
    print(show_out)
    # 将结果保存起来
    results.append([train_loss.data.numpy() / len(train_set),
                    valid_loss.data.numpy() / len(train_set),
                   1.0 * errors / len(valid_set)
                   ])
# 保存、提取模型(为展示用)
torch.save(rnn,'rnn.mdl')
rnn = torch.load('rnn.mdl')

观察 RNN 模型的学习结果

下面让 n 从 0 循环到 20,考察随着序列的增强,模型的预测效果会有怎样的变化。只有当模型能够预测出最后一个 1 以及后面应该是跟 2(字串结束字符)才算预测正确,也就意味着模型记忆住了 n 这个数字。

# 让n取0到20,看RNN是否能够成功预测下一个字符
for n in range(20):

    inputs = [0] * n + [1] * n
    inputs.insert(0, 3)
    inputs.append(2)
    outstring = ''
    targets = ''
    diff = 0
    hiddens = []
    hidden = rnn.initHidden()
    for t in range(len(inputs) - 1):
        x = Variable(torch.LongTensor([inputs[t]]).unsqueeze(0))
        y = Variable(torch.LongTensor([inputs[t + 1]]))
        output, hidden = rnn(x, hidden)

        mm = torch.max(output, 1)[1][0]
        outstring += str(mm.data.numpy())
        targets += str(y.data.numpy()[0])

        diff += 1 - mm.eq(y).data.numpy()[0]
    print(n)
    print(outstring)
    print(targets)
    print('Diff:{}'.format(diff))

可以看到,对于大部分的预测序列来说,经过长时间训练的 RNN 仅仅犯少量的错误,就是当输入从0变为1的那个瞬间。当 n 等于 14 时,开始出现大量错误,所以可以认为这个简单的 RNN 神经网络模型的记忆容量差不多就是 13。

四、使用 LSTM 模型进行序列生成

实现一个LSTM

那么下面就开始实现这个 LSTM 模型,因为 PyTorch 同样将 LSTM 结构封装的如此简洁,以至于 LSTM 模型代码几乎和 RNN 模型代码没有什么区别。

唯一不同的就是模型中调用 RNN 的位置现在改为了调用 LSTM 结构,即:

self.lstm = nn.LSTM(hidden_size, hidden_size, num_layers, batch_first = True)

LSTM 函数的各个参数意义也是与 RNN 相同的。

# 一个手动实现的LSTM模型,除了初始化隐含但愿部分,所有代码基本与SimpleRNN相同

class SimpleLSTM(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, num_layers = 1):
        super(SimpleLSTM, self).__init__()

        self.hidden_size = hidden_size
        self.num_layers = num_layers
        # 一个embedding层
        self.embedding = nn.Embedding(input_size, hidden_size)
        # 隐含层内部的相互链接
        self.lstm = nn.LSTM(hidden_size, hidden_size, num_layers, batch_first = True)
        self.fc = nn.Linear(hidden_size, output_size)
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, input, hidden):

        # 先进行embedding层的计算,它可以把一个
        # x的尺寸:batch_size, len_seq, input_size
        x = self.embedding(input)
        # x的尺寸:batch_size, len_seq, hidden_size
        # 从输入到隐含层的计算
        output, hidden = self.lstm(x, hidden)
        # output的尺寸:batch_size, len_seq, hidden_size
        # hidden: (layer_size, batch_size, hidden_size),(layer_size, batch_size,hidden_size)
        output = output[:,-1,:]
        # output的尺寸:batch_size, hidden_size
        output = self.fc(output)
        # output的尺寸:batch_size, output_size
        # softmax函数
        output = self.softmax(output)
        return output, hidden

    def initHidden(self):
        # 对隐含单元的初始化
        # 注意尺寸是: layer_size, batch_size, hidden_size
        # 对隐单元的初始化
        # 对引单元输出的初始化,全0.
        # 注意hidden和cell的维度都是layers,batch_size,hidden_size
        hidden = Variable(torch.zeros(self.num_layers, 1, self.hidden_size))
        # 对隐单元内部的状态cell的初始化,全0
        cell = Variable(torch.zeros(self.num_layers, 1, self.hidden_size))
        return (hidden, cell)

虽然说 LSTM 模型的代码与 RNN 几乎相同,但有一个地方需要注意一下。就是在初始化隐藏层状态的时候,LSTM 除了初始化隐藏层的状态,还初始化了隐含层内部细胞的状态,也就是各个“门控单元”的状态。

训练简单 LSTM 模型

与 RNN 模型相同,下面进行 LSTM 模型的训练。首先实例化模型,定义模型的损失函数与优化算法:

lstm = SimpleLSTM(input_size = 4, hidden_size = 1, output_size = 3, num_layers = 1)
criterion = torch.nn.NLLLoss()
optimizer = torch.optim.Adam(lstm.parameters(), lr = 0.001)

然后是定义训练函数:

train_loss = 0

def trainLSTM(epoch):
    global train_loss
    train_loss = 0
    np.random.shuffle(train_set)
    # 开始所有训练数据的循环
    for i, seq in enumerate(train_set):
        loss = 0
        hidden = lstm.initHidden()
        # 开始每一个字符的循环
        for t in range(len(seq) - 1):
            x = Variable(torch.LongTensor([seq[t]]).unsqueeze(0))
            # x的尺寸:batch_size, len_seq, hidden_size
            y = Variable(torch.LongTensor([seq[t + 1]]))
            # y的尺寸:batch_size, data_dimension
            output, hidden = lstm(x, hidden)
            # output的尺寸:batch_size, data_dimension
            # hidden: (layer_size, batch_size, hidden_size),(layer_size, batch_size,hidden_size)
            loss += criterion(output, y)
        loss = 1.0 * loss / len(seq)
        optimizer.zero_grad()
        loss.backward(retain_graph = True)
        optimizer.step()
        train_loss += loss
        if i > 0 and i % 500 == 0:
            print('第{}轮, 第{}个,训练Loss:{:.2f}'.format(epoch,
                                                    i,
                                                    train_loss.data.numpy() / i
                                                   ))

然后是验证函数

valid_loss = 0
errors = 0
show_out = ''

def evaluateRNN():
    global valid_loss
    global errors
    global show_out
    valid_loss = 0
    errors = 0
    show_out = ''
    for i, seq in enumerate(valid_set):
        loss = 0
        outstring = ''
        targets = ''
        diff = 0
        hidden = lstm.initHidden()
        for t in range(len(seq) - 1):
            x = Variable(torch.LongTensor([seq[t]]).unsqueeze(0))
            # x的尺寸:batch_size, len_seq, hidden_size
            y = Variable(torch.LongTensor([seq[t + 1]]))
            # y的尺寸:batch_size, data_dimension
            output, hidden = lstm(x, hidden)
            # output的尺寸:batch_size, data_dimension
            # hidden: (layer_size, batch_size, hidden_size),(layer_size, batch_size,hidden_size)
            mm = torch.max(output, 1)[1][0]
            outstring += str(mm.data.numpy())
            targets += str(y.data.numpy()[0])
            loss += criterion(output, y)

            diff += 1 - mm.eq(y).data.numpy()[0]
        loss = 1.0 * loss / len(seq)
        valid_loss += loss
        errors += diff
        if np.random.rand() < 0.1:
            show_out = outstring + '\n' + targets
    print(output[0][2].data.numpy())

下面正式进行 LSTM 模型的训练。LSTM 模型的训练流程与 RNN 模型是一样的。

num_epoch = 20
results = []

# 开始训练循环
for epoch in range(num_epoch):
    trainLSTM(epoch)
    # 在校验集上跑结果
    evaluateRNN()
    print('第{}轮, 训练Loss:{:.2f}, 校验Loss:{:.2f}, 错误率:{:.2f}'.format(epoch,
                                                               train_loss.data.numpy() / len(train_set),
                                                               valid_loss.data.numpy() / len(valid_set),
                                                               1.0 * errors / len(valid_set)
                                                              ))
    print(show_out)
    results.append([train_loss.data.numpy() / len(train_set),
                    valid_loss.data.numpy() / len(train_set),
                   1.0 * errors / len(valid_set)
                   ])
# 保存、提取模型(为展示用)
torch.save(lstm,'lstm.mdl')
lstm = torch.load('lstm.mdl')

再来看看这个# 让n取0到20,看SimpleLSTM是否能够成功预测下一个字符
for n in range(20):

inputs = [0] * n + [1] * n
inputs.insert(0, 3)
inputs.append(2)
outstring = ''
targets = ''
diff = 0
hiddens = []
hidden = lstm.initHidden()
for t in range(len(inputs) - 1):
    x = Variable(torch.LongTensor([inputs[t]]).unsqueeze(0))
    y = Variable(torch.LongTensor([inputs[t + 1]]))
    output, hidden = lstm(x, hidden)

    mm = torch.max(output, 1)[1][0]
    outstring += str(mm.data.numpy())
    targets += str(y.data.numpy()[0])

    diff += 1 - mm.eq(y).data.numpy()[0]
print(n)
print(outstring)
print(targets)
print('Diff:{}'.format(diff))LSTM网络在测试集上的表现如何

原文地址:https://www.cnblogs.com/wwj99/p/12231080.html

时间: 2024-10-07 15:27:39

Pytorch基础——使用 RNN 生成简单序列的相关文章

PyTorch基础——使用神经网络识别文字中的情感信息

一.介绍 知识点 使用 Python 从网络上爬取信息的基本方法 处理语料"洗数据"的基本方法 词袋模型搭建方法 简单 RNN 的搭建方法 简单 LSTM 的搭建方法 二.从网络中抓取并处理数据 引入相关包 下载所需数据并解压 链接:https://pan.baidu.com/s/1Jg5NPxc9L-M8Tdgh70Tvig 提取码:dpqq # 导入程序所需要的程序包 #PyTorch用的包 import torch import torch.nn as nn import tor

PyTorch基础——机器翻译的神经网络实现

一.介绍 内容 "基于神经网络的机器翻译"出现了"编码器+解码器+注意力"的构架,让机器翻译的准确度达到了一个新的高度.所以本次主题就是"基于深度神经网络的机器翻译技术". 我们首先会尝试使用"编码器+简单解码器"的构架,来观察普通编码器-解码器构架能够取得的效果.然后会尝试"编码器+带有注意力机制的解码器"构架,看看加上注意力能让模型获得怎样的提高. 实验知识点 机器翻译"平行语料"的

NHibernate 映射基础(第三篇) 简单映射、联合主键

NHibernate 映射基础(第三篇) 简单映射.联合主键 NHibernate完全靠配置文件获取其所需的一切信息,其中映射文件,是其获取数据库与C#程序关系的所有信息来源. 一.简单映射 下面先来一个简单的例子,然后随着不断地对这个例子修修改改,从而真正了解映射文件.具体的资料可以查看http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html 先来看一张表: 映射文件Product.hbm.xml: <?xml versi

Matlab生成M序列的伪随机码

伪随机编码中较常用的是m序列,它是线性反馈移位寄存器序列的一种,其特点是在相同寄存器级数的情况下输出序列周期最长.线性反馈移位寄存器的工作原理是,给定所有寄存器一个初始值,当移位脉冲到来时,将最后一级寄存器的值输出,同时将第 i级的寄存器内容存储到第 i+1 级中,此外将每一级的寄存器输出按照一定的线性运算规则计算出一个值,并将该值存入第一级寄存器中.随着移位脉冲的累加,线性反馈移位寄存器的输出可以组成一个序列,称之为移位寄存器序列[71]. 图3.5 线性反馈移位寄存器 MATLAB生成M序列

数字信号处理MATLAB简单序列

数字信号处理应用的几个基本序列: 1 单位样本序列 function mainImseq() clc clear disp('生成抽样序列'); y=imseq(1,1,5); %调用样本函数,此时序列下标以1开头(1~5之间5个数,下标为1的抽样值为1) %子函数imseq:抽样函数 function [x,n]=imseq(n0,n1,n2) n=[n1:n2]; x=[(n-n0) ==0 ] 2 单位阶越序列 产生u(n) function mainImseq() clc clear d

生成数字序列命令(7)

生成数字序列命令:seq,shuf 7.1.seq 功能:打印数字序列 语法:seq [OPTION]... LAST seq [OPTION]... FIRST LAST seq [OPTION]... FIRST INCREMENT LAST 常用选项: -f  使用printf样式格式 -s  指定分隔符,默认换行符\n -w  等宽,用0填充 示例: 数字序列: 方法1: [[email protected] ~]# seq 10 1 2 3 4 5 6 7 8 9 10 方法2: fo

扩增子分析解读4去嵌合体 非细菌序列 生成代表性序列和OTU表

本节课程,需要先完成 扩增子分析解读1质控 实验设计 双端序列合并 2提取barcode 质控及样品拆分 切除扩增引物 3格式转换 去冗余 聚类 先看一下扩增子分析的整体流程,从下向上逐层分析 分析前准备 # 进入工作目录 cd example_PE250 上一节回顾:我们制作了Usearch要求格式的Fasta文件,对所有序列进行去冗余和低丰度过滤,并聚类生成了OTU. 接下来我们对OTU进一步去除嵌合体,并生成代表性序列和OTU表. 什么是chimeras(嵌合体)? 嵌合体序列由来自两条或

学习笔记:利用GDI+生成简单的验证码图片

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 学习笔记:利用GDI+生成简单的验证码图片 1 /// <summary> 2 /// 单击图片时切换图片 3 /// </summary> 4 /// <param name="sender">&

IOS基础_Block语法的简单使用

开始学IOS的时候没怎么接触过block语句,在后来用到的越来越多,就不得不学了,刚开始理解比较困难的,然后自己做了一个例子就慢慢理解了,不说废话了,上代码: 正常的简单地申明调用一个block语句是这样的: //申明 int (^yxpBlock)(int, int)  =^(int a ) {return a*a ;}; 说明:返回值(^语句块名称)(传人参数类型)=^(传人参数){主体}: //调用 int result = square(5); 我建了一个测试项目包含了(yxpAppDe