各位人工智能爱好者,大家好!

由TinyMind发起的 #第一届汉字书法识别挑战赛# 正在火热进行中,比赛才开始2周,已有数只黑马冲进榜单。目前TOP23全部为90分以上了,可谓竞争激烈,高手如林。不是比赛太简单,是大佬们太厉害了啊!

No.1微胖君(microfat_htu)目前以99.01高分领衔榜首,还未报名的同学欢迎点击"原文链接"参赛,向这些同学发起挑战~~

4.24 榜单

本次比赛主要是以学习交流为目的,吸引了不少萌新们报名参赛~虽是入门级别的赛题,对于没动手实战过的同学,还是有些不知所措。为此TinyMind特邀战场中奋勇拼搏的三名前锋,为大家整理了一些经验心得,用不同的解题思路,以启发新手们如何开动,参与到本次书法识别比赛中。

以下为参赛ID:真的学不会 的经验分享

汉字书法识别入门

前段时间参加了一次TinyMind举办的汉字书法识别挑战赛,说是挑战赛其实就是一场练习赛。为一些刚刚入门的同学和没有比赛经验的同学提供了一个探索图像识别领域的平台。我目前是暂列榜首(没想到转眼就被超越了-。-),所以把自己的思路和想法稍微做一个分享,给有需要的人提供一个base line。

先来看数据集~~

100个汉字的训练集

10000张书法图片的测试集

上面的训练集总共有100个汉字,每一个汉字都有400张不同字体的图片,数据量上来看算是一个比较小的数据集。

等等,看到的确定是汉字吗,第一眼望过去我是真的emmmmm.....甲骨文,篆体各种字体都冒出来了。先喝口水冷静一下,仔细看一看发现图片都是gray的。想了一想突然觉得这个和mnist并没有太大的区别只是字体更加复杂一些,可能要用稍微深一点的网络来训练。

图片看完了,那么开始撸代码了。分析终究是分析,还是实践才能说明一切。

数据集划分


竞赛中只给了train和test,所以需要自己手动划分一个val来做模型训练的验证测试。在这里简单说明一下经常用的两种划分数据集的方法。

  • 本地划分

  • 内存划分

本地划分:图片是按照文件夹分类的,所以只需要从每个文件夹中按ratio抽取部分图片到val中即可,当然不要忘记了shuffle。
内存划分:把所有图片和标签读进内存中,存为list或者array然后shuffle后按长度划分。前提是把数据读进去内存不会爆炸掉。内存划分只适合小型数据集,不然会Boom!!!

注:划分数据集的时候一定要打乱数据,shuffle很重要!!!

1def move_ratio(data_list, original_str, replace_str):
2    for x in data_list:
3        fromImage = Image.open(x)
4        x = x.replace(original_str, replace_str)
5        fromImage.save(x)

注:这里只给出部分代码,文章最下面github有完整链接。

1for d in $(ls datadir); do                        
2    for f in $(ls datadir/$d | shuf | head -n 100 ); do
3        mkdir -p valid_dir/$d/
4        mv datadir/$d/$f valid_dir/$d/;
5    done;
6done

注:这里引用dwSun的linux shell脚本,如果想用简单脚本实现也可以采用他的代码~

模型建立与数据预处理


对于CNN网络来说,大的数据集对应大的训练样本,如果小的数据集想要用深层次的网络来训练的话,那么必不可少的一步就是数据增强。

数据增强的大部分方法,所有深度学习框架都已经封装好了。这里我采用的是keras自带的数据增强方法。

1from keras.preprocessing.image import ImageDataGenerator
2datagen = ImageDataGenerator(
3    # horizontal_flip=True,
4    width_shift_range=0.15,
5    height_shift_range=0.15,
6    rescale=1 / 255
7)

由于汉字是具有笔画顺序的,所以做了翻转以后训练的效果不是很好。这里就做了一个宽度和高度的偏移,由于给的数据集图片长宽不是固定的而且字体的内容也是有长有短。所以用这两种增强方式可以提高模型的准确率,结果测试这两种方式还是有效的。

数据处理完了,那么下面就是我们可爱的CNN网络模型了

cnn一把梭

嗯,就是干。

1# bn + prelu
2def bn_prelu(x):
3    x = BatchNormalization()(x)
4    x = PReLU()(x)
5    return x
6# build baseline model
7def build_model(out_dims, input_shape=(128, 128, 1)):
8    inputs_dim = Input(input_shape)
9    x = Conv2D(32, (3, 3), strides=(2, 2), padding='valid')(inputs_dim)
10    x = bn_prelu(x)
11    x = Conv2D(32, (3, 3), strides=(1, 1), padding='valid')(x)
12    x = bn_prelu(x)
13    x = MaxPool2D(pool_size=(2, 2))(x)
14    x = Conv2D(64, (3, 3), strides=(1, 1), padding='valid')(x)
15    x = bn_prelu(x)
16    x = Conv2D(64, (3, 3), strides=(1, 1), padding='valid')(x)
17    x = bn_prelu(x)
18    x = MaxPool2D(pool_size=(2, 2))(x)
19    x = Conv2D(128, (3, 3), strides=(1, 1), padding='valid')(x)
20    x = bn_prelu(x)
21    x = MaxPool2D(pool_size=(2, 2))(x)
22    x = Conv2D(128, (3, 3), strides=(1, 1), padding='valid')(x)
23    x = bn_prelu(x)
24    x = AveragePooling2D(pool_size=(2, 2))(x)
25    x_flat = Flatten()(x)
26    fc1 = Dense(512)(x_flat)
27    fc1 = bn_prelu(fc1)
28    dp_1 = Dropout(0.3)(fc1)
29    fc2 = Dense(out_dims)(dp_1)
30    fc2 = Activation('softmax')(fc2)
31    model = Model(inputs=inputs_dim, outputs=fc2)
32    return model

这里用了6个简单的卷积层,和PRelu+bn层。

下面是一个比较大的模型ResNet50,模型是已经merge在了keras的applications中,可以直接用。不过需要调整分类层。

1def resnet50_100(feat_dims, out_dims):
2    # resnett50 only have a input_shape=(128, 128, 3), if use resnet we must change
3    # shape at least shape=(197, 197, 1)
4    resnet_base_model = ResNet50(include_top=False, weights=None, input_shape=(128, 128, 1))
5    # get output of original resnet50
6    x = resnet_base_model.get_layer('avg_pool').output
7    x = Flatten()(x)
8    fc = Dense(feat_dims)(x)
9    x = bn_prelu(fc)
10    x = Dropout(0.5)(x)
11    x = Dense(out_dims)(x)
12    x = Activation("softmax")(x)
13    # buid myself model
14    input_shape = resnet_base_model.input
15    output_shape = x
16    resnet50_100_model = Model(inputs=input_shape, outputs=output_shape)
17    return resnet50_100_model

好了,炼丹炉有了接下来就是你懂的。

训练模型


训练模型和调参真的是一个技术活,这里我跑了共40个epoch。思路只有一个那就是先把train的数据跑到loss下降并且先过拟合再说。只要过拟合了后面的一切都好调整了,如果训练数据都不能到过拟合或者99以上那么要仔细想想数据量够不够和模型的选择了。

loss

acc

可以很清楚的看出来,训练数据集已经过拟合了。我用的优化器是sgd,学习率设置的是lr=0.01。val_acc可以跑到了0.94左右,这是一个比较正常的训练水平。还可以进一步的提高。

提高方法


  • 数据增强:采取其他的数据增强方法进一步扩大训练数据,这里可以采用GAN来生成近似于真实图片的数据。

  • 衰减学习率:当到达一定epoch的时候,loss不再下降了这个时候可以通过减小学习率的方法进一步训练。

  • 模型融合:模型融合的方法在大部分数据集上都会有所提高,这个是最常用的一种竞赛方式。

以上就是我自己做的流程和思路,提交结果和评测的代码写在我的github上面了,有兴趣参加比赛练手的同学可以参考一下。

github地址:https://github.com/FlyEgle/chinese_font_recognition/

好多小伙伴是从开发或者是其他工程上转到AI的,所以下面我给有需要的同学列举出一些必要的基础知识点.

基础知识


  • 数学:线性代数和概率论是必须要会的,而且基本的概念和计算都要懂。可以把高数,线性代数和概率论看一遍,这里推荐李航的统计学习方法。

  • 图像处理:如果是做图像方面的小伙伴,那么需要把冈萨雷斯的图像处理那本巨作看一遍,需要懂基本的图像概念和基本方法。

  • 机器学习:周志华的西瓜书

  • 深度学习:

如果能把这几本书完全吃透那也很厉害了,当然学习知识点的途径还有很多。

  • 知乎

  • 微信公众号

  • Google

  • TinyMind

加油!!

以下为参赛ID:Link 的经验分享

深度学习入门指南:从零开始TinyMind汉字书法识别

  • 环境搭建

  • 数据导入

  • 启动网络


环境搭建:

对入门来说,最容易的还是在windows下进行开发。而且现在各种深度学习架构大都支持windows,因此如果只是入门深度学习,最好还是从windows开始。不过因为github上提交的代码全都运行在linux环境下,因此希望大家最终能转向linux下,话不多说,现在开始。

我们选用的深度学习架构是pytorch, 相比于tensorflow,pytorch更加简单易用,而且符合python的编程习惯,官网的支持也足够完善。

环境搭建步骤

  1. 安装Anaconda, 装python3.6版本的,至于为啥用python3这都2018年了,就别用上古版本了

  2. 安装pycharm,将pycharm的解释器改为anaconda安装目录下的python。当然用别的IDE也可以,但是我习惯用pycahrm了,如果大家用别的IDE这步另当别论

  3. 安装深度学习架构pytorch, 到了最重要的步骤了,如果没有英伟达显卡,或者显卡不支持请忽略1-3步

    1. 安装英伟达显卡驱动

    2. 安装CUDA

    3. 安装Cuddn

    4. 安装pytorch gpu版 (没有显卡的装cpu版)具体方法参见知乎这篇文章 https://zhuanlan.zhihu.com/p/26871672 选择自己对应的版本、系统、cuda版本,按照命令直接装就可以

数据导入

数据下载在TinyMind的比赛网站 http://www.tinymind.cn/competitions/41 下载解压后是两部分,分别是train和test1,其中train是训练集,test1是用来提交评分的测试集 为了导入图片数据,需要调用opencv,没装opencv的话就先装opencv

1conda install -c https://conda.binstar.org/menpo opencv

1import os
2import numpy as np
3import torch
4import torch.utils.data as data
5import cv2
6from PIL import Image
7from tqdm import tqdm
8trainpath = 'E:\\Code\\TMD1st\\train\\' #这是我的储存路径,windows下的路径是需要用\\隔开的,linux是反斜杠/
9testpath = 'E:\\Code\\TMD1st\\test1\\'
10words = os.listdir(trainpath)   # 按时间排序 从早到晚
11category_number = len(words) # 一共有多少个字
12img_size = (256, 256) #将图片大小统一设定为这个值
13def loadOneWord(order):
14    path = trainpath + words[order] + '\\'
15    files = os.listdir(path)
16    datas = []
17    for file in files:
18        file = path + file
19        img = np.asarray(Image.open(file))
20        img = cv2.resize(img, img_size)
21        datas.append(img)
22    datas = np.array(datas)
23    labels = np.zeros([len(datas), len(words)], dtype=np.uint8)
24    labels[:, order] = 1
25    return datas, labels
26def transData():    #将所有数据转存,以后就不用每次都从原始数据读取了
27    num = len(words)
28    datas = np.array([], dtype=np.uint8)
29    datas.shape = -1, 256, 256
30    labels = np.array([], dtype=np.uint8)
31    labels.shape = -1, 100
32    for k in range(num):
33        data, label = loadOneWord(k)
34        datas = np.append(datas, data, axis=0)
35        labels = np.append(labels, label, axis=0)
36        print('loading', k)
37    np.save('data.npy', datas) #将数据和标签分别存为data和label
38    np.save('label.npy', labels)

将转存完的结果读出来看一下

1if __name__ == '__main__':
2    datas = np.load('data.npy')
3    labels = np.load('label.npy')
4    index = np.arange(0, len(datas), 1, dtype=np.int)
5    print(datas.shape, labels.shape)

(40000, 256, 256) (40000, 100)

我是将40000个图像的label按照one-hot编码存的,这么干其实浪费空间,但是反正也没几兆,就懒得改了,index那一行就是专为将ong-hot转label

这才将数据转存,为了训练时给pytorch使用,最方便的方法是使用pytorch做好的loader工具,为此需要实现自己的data.Dataset。只需继承data.Dataset,并且重写__getitem__和__len__两个方法就可以。

1class TrainSet(data.Dataset):
2    def __init__(self, eval=False):
3        datas = np.load('data.npy') #装载
4        labels = np.load('label.npy')
5        index = np.arange(0, len(datas), 1, dtype=np.int) #换one-hot为label
6        np.random.seed(123)
7        np.random.shuffle(index)
8        if eval:    #如果eval为真,就取10%作为验证集,设定随机数种子是为了每次取出来的都是固定的10%,以免将验证集用于训练
9            index = index[:int(len(datas) * 0.1)]
10        else:
11            index = index[int(len(datas) * 0.1):]
12        self.data = datas[index]
13        self.label = labels[index]
14        np.random.seed()
15    def __getitem__(self, index):
16        return torch.from_numpy(self.data[index]), \
17               torch.from_numpy(self.label[index])
18    def __len__(self):
19        return len(self.data)

完成dataset后只要使用torch.utils.data.DataLoader就可以自动划分batch。

启动网络

无论网络结构如何,用网络进行训练的整个过程是相同的

1import torch
2import torch.optim as optim
3from torch.autograd import Variable
4import torch.nn as nn
5import data
6import torch.nn.functional as F
7n_epoch, batch_size = 25, 8 # 设置遍历次数及每个batch的大小
8trainset = data.TrainSet(eval=False) #实例化上面定义的数据集对象
9trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True) #用trainset实例化loader
10evalset = data.TrainSet(eval=True)  #验证集
11evalloader = torch.utils.data.DataLoader(evalset, batch_size=batch_size, shuffle=True)
12net = Net() # 实例化模型
13if torch.cuda.is_available():   # 将模型移到GPU上
14    net.cuda()
15criterion = nn.CrossEntropyLoss()   #损失函数使用交叉熵
16optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=1e-1, weight_decay=1e-4) #优化器使用SGD 学习率1e-3
17def train(epoch):
18    net.train() # 经模型切换到训练模式
19    correct = 0
20    sum = 0
21    for batch_index, (datas, labels) in enumerate(trainloader, 0):  #从loader装载数据
22        labels = labels.max(1)[1]
23        datas = Variable(datas).float()
24        datas = datas.view(-1, 1, 256, 256)
25        labels = Variable(labels).long()
26        if torch.cuda.is_available():   #数据转移到GPU
27            datas = datas.cuda()
28            labels = labels.cuda()
29        optimizer.zero_grad()   # 每次前项计算之前,将优化器梯度清零
30        outputs = net(datas)    # 前项计算
31        loss = criterion(outputs, labels) # 根据结果和label计算损失函数
32        loss.backward() # 做反向传播
33        optimizer.step() # 用优化器进行一次更新
34        pred_choice = outputs.data.max(1)[1]    # 前向输出计算最大的一个作为最可能的输出
35        correct += pred_choice.eq(labels.data).cpu().sum() # 统计正确个数
36        sum += len(labels)  # 总数
37        # 输出每次计算的信息
38        print('batch_index: [%d/%d]' % (batch_index, len(trainloader)),
39              'Train epoch: [%d]' % (epoch),
40              # 'acc:%.4f p:%.4f r:%.4f F1:%.4f' % (acc, p, r, F1),
41              'correct/sum:%d/%d, %.4f' % (correct, sum, correct / sum))
42def eval(epoch):    # 用验证集做类似过程,只是不计算梯度、不更新参数
43    net.eval()
44    correct = 0
45    sum = 0
46    for batch_index, (datas, labels) in enumerate(evalloader, 0):
47        labels = labels.max(1)[1]
48        datas = Variable(datas).cuda().float()
49        datas = datas.view(-1, 1, 256, 256)
50        labels = Variable(labels).cuda().long()
51        # optimizer.zero_grad()
52        outputs = net(datas)
53        # loss = criterion(outputs, labels)
54        # loss.backward()
55        # optimizer.step()
56        pred_choice = outputs.data.max(1)[1]
57        correct += pred_choice.eq(labels.data).cpu().sum()
58        sum += len(labels)
59        print('batch_index: [%d/%d]' % (batch_index, len(evalloader)),
60              'Eval epoch: [%d]' % (epoch),
61              # 'acc:%.4f p:%.4f r:%.4f F1:%.4f' % (acc, p, r, F1),
62              'correct/sum:%d/%d, %.4f' % (correct, sum, correct / sum))
63if __name__ == '__main__':
64    for epoch in range(n_epoch):
65        train(epoch)
66        eval(epoch)

如此,我们就完成了从原始数据制作dataset送入loader并且启动网络的所有代码。 等等,我们忘记了最重要的部分,我们没有定义网络的结构。 Net这里,这是一个继承自nn.Moudule的类,只要在这个类中定义网络的前向计算即可,反向计算会由pytorch自动实现。

为了简单起见,我们只举一个简单的例子,这个网络是随便写的,完全没有任何合理性的考虑,但至少能开始训练了。

1class net(nn.Module):
2    def __init__(self):
3        super(net, self).__init__()
4        self.pool = nn.MaxPool2d(2)
5        self.drop = nn.Dropout(p=0.5)
6        self.conv1 = nn.Conv2d(1, 32, 7, stride=2, padding=3)
7        self.norm1 = nn.BatchNorm2d(32)
8        self.conv2 = nn.Conv2d(32, 32, 3, stride=1, padding=1)
9        self.norm2 = nn.BatchNorm2d(32)
10        self.conv3 = nn.Conv2d(32, 64, 3, stride=1, padding=1)
11        self.norm3 = nn.BatchNorm2d(64)
12        # Sequential 是连续操作的写法
13        self.convs = nn.Sequential(nn.Conv2d(64, 128, 3, stride=1, padding=1),
14                                   nn.BatchNorm2d(128),
15                                   nn.ReLU(),
16                                   nn.Conv2d(128, 128, 3, stride=1, padding=1),
17                                   nn.BatchNorm2d(128),
18                                   nn.ReLU(),
19                                   )
20        self.out_layers = nn.Sequential(nn.Linear(128 * 8 * 8, 1024),
21                                        nn.BatchNorm1d(1024),
22                                        nn.ReLU(),
23                                        nn.Linear(1024, 256),
24                                        nn.BatchNorm1d(256),
25                                        nn.ReLU(),
26                                        nn.Linear(256, 100),
27                                        nn.BatchNorm1d(100),
28                                        nn.ReLU(),
29                                        )
30    def forward(self, x):
31        x = F.relu(self.norm1(self.conv1(x)))   # 卷积 BN ReLU
32        x = self.pool(x)                        # 池化
33        x = F.relu(self.norm2(self.conv2(x)))  # 卷积 BN ReLU
34        x = F.relu(self.norm3(self.conv3(x)))  # 卷积 BN ReLU
35        x = self.pool(x)
36        x = self.convs(x)                      # 连续操作,里面是 conv -> BN -> ReLU -> conv -> BN -> ReLU
37        x = self.pool(x)
38        x = x.view(-1, 128 * 8 * 8)             # 将图像拉直为向量
39        x = self.drop(x)
40        x = self.out_layers(x)
41        return x

这样,代码就完整了,运行开始以后我么你就恩能够看到训练正确率从0慢慢的向上爬。当然,这个网络是随意写的,性能肯定极其的差,但至少举了一个栗子。

我们都知道,深度学习也叫炼丹。所以接下来的活便是研究拜读各个大牛级炼丹师的的炼丹秘籍(论文),学习人家先进的炼丹手法(trick),把我们的栗子给炼成金丹。

五年炼丹,三年悟道,炼丹一道,非大毅力大智慧者不可成。吾等当昼夜苦修,方有机缘窥得一丝丹道真谛,与诸君共勉。

源代码

链接地址:https://github.com/Link2Link/TinyMind-start-with-0

以下为参赛ID:microfat_htu 的经验分享

前一段时间在用迁移学习实现图像分类Github,正好赶上这次书法识别比赛,就想尝试用迁移学习的方法实现书法图像分类。本来没有抱太大希望,因为根据迁移学习理论,训练源域模型的数据应与训练目标域的数据有相似的特征分布,然而,ILSVRC数据集中并没有汉字符号类别,所以,期望的最好结果是能够收敛。但,事实出乎意料,不仅收敛,而且得到99.01%的测试准确率(看来我是低估深度模型的特征提取能力了)。

学人工智能一次竞赛都不打?闹呢?相关推荐

  1. 【人工智能】人工智能是什么?如何入门人工智能?我们为什么要学人工智能?

    目录 什么是人工智能? 人工智能都要学一些什么? 机器学习与人工智能,深度学习的关系: 如何成为一名机器学习的专家 ? 机器学习--入门 1.B站(Bilibili)的一位up主:KnowingAI. ...

  2. 学python需要什么-想要学人工智能需要学些什么python的知识

    人工智能包含常用机器学习和深度学习两个很重要的模块,而python拥有matplotlib.Numpy.sklearn.keras等大量的库,像pandas.sklearn.matplotlib这些库 ...

  3. 马云:我看到很多人去学MBA 但回来时都变蠢了

     马云:我看到很多人去学MBA 但回来时都变蠢了 2017年03月24日 11:22 每日经济新闻 微博 微信 空间 分享 653 马云最新演讲:我看到很多人去学MBA 但回来时都变蠢了 每经记者 ...

  4. 从零开始学python人工智能课程_从零开始学人工智能(12)--Python · 决策树(零)· 简介...

    原标题:从零开始学人工智能(12)--Python · 决策树(零)· 简介 感谢关注天善智能,走好数据之路↑↑↑ 欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直 ...

  5. 32岁学python 人工智能_python深入学习好还是直接学人工智能好?

    python深入学习好还是直接学人工智能好 这个其实是理解上的一个偏差,人工智能是一个领域,而深度学习是门技术 有很多人说不会机器学习,深度学习无法实现人工智能,这句话放在5-6年前完全正确,而放眼现 ...

  6. 为什么说学人工智能一定要学Python?

    有很多人在问小千,为什么说学人工智能一定要学Python?运行速度慢不好之类的,今天就让小千谈谈自己对于Python的感受. 一.先来说说Python的前景 随着"大数据"&quo ...

  7. python人工智能要学什么_为什么学人工智能首推Python 需要学习哪些知识

    原标题:为什么学人工智能首推Python 需要学习哪些知识 为何学人工智能首推Python?需要学习哪些知识?简单地讲,人工智能就是图像处理,数据处理,语言处理等多技术融合,在我们生活中经常可见.比如 ...

  8. 想学人工智能从哪入手?

    没有基础怎么学人工智能?该选择什么方式入门?作为当前最火热的人工智能,越来越多的人发现这一行业的潜力,很多人开始转行,进入这一行业.而想要快速进入这一行业,大部分人选择了专业学习.市场上的机构有很多, ...

  9. 人工智能学c语言还是python-python深入学习好还是直接学人工智能好?

    python深入学习好还是直接学人工智能好 这个其实是理解上的一个偏差,人工智能是一个领域,而深度学习是门技术 有很多人说不会机器学习,深度学习无法实现人工智能,这句话放在5-6年前完全正确,而放眼现 ...

最新文章

  1. 迁移学习:如何使用TensorFlow对图像进行分类
  2. 《系统集成项目管理工程师》必背100个知识点-19项目管理计划的内容
  3. Oracle实现数据增删改的sql语句实例
  4. escape、encodeURI 、encodeURIComponent 编码与解码
  5. 银行招聘网计算机类笔试,中国人民银行计算机类笔试模拟题
  6. Androud 如何有效减少重复代码
  7. (转)基因芯片数据GO和KEGG功能分析
  8. java的add方法的使用_Java HashSet add()方法与示例
  9. hasset java_java HashSet的使用
  10. Particle Filter Tutorial 粒子滤波:从推导到应用(四)
  11. Java基础知识(JAVA中String、StringBuffer、StringBuilder类的区别)
  12. 用python实现遗传算法
  13. vue中延时函数用法
  14. 阿里巴巴实习生电话面试
  15. 调试经验——Win 10 Excel中Alt+Tab不能切换窗口的解决方法
  16. 华为云 搭建 Zabbix监控服务
  17. lightoj1138
  18. PHP开发基于Mirai的QQ机器人(一)
  19. 百兆以太网口通信速率_以太网发送速率(传输速率)和传播速率
  20. matlab 概率分布程序,常见的概率分布(matlab作图)

热门文章

  1. 2022年清华大学计算机考研复试时间及要求分别是什么
  2. 三年经验前端社招——众安保险
  3. 激光测距VL53L0X中断模式 源代码 已测试
  4. autojs-toast-多彩气泡
  5. DSO windowed optimization 代码 (2)
  6. 图书管理系统-书籍归还
  7. Android问题:java.lang.UnsatisfiedLinkError: No implementation found for异常解决方法
  8. WebSocket 协议详述( java在线聊天室_上篇)
  9. 浙江理工大学计算机研究生导师,浙江理工大学
  10. [附源码]Python计算机毕业设计Django儿童早教课程管理系统论文2022