快来生成你专属的英文名吧(使用字符级RNN)!

news2024/11/22 12:01:45

目录

一.前言

二.准备数据

三.构造神经网络

四.训练

五.网络采样(预测)


一.前言

数据集为18个国家的姓氏,任务是根据训练得到的模型,在给定国家类别和首字母后,能得到一个与该国人名非常相似的一个人名。

> python sample.py Russian RUS
Rovakov
Uantov
Shavakov

> python sample.py German GER
Gerren
Ereng
Rosher

> python sample.py Spanish SPA
Salla
Parer
Allan

> python sample.py Chinese CHI
Chan
Hang
Iun

我们使用只有几层线性层的小型RNN。最大的区别在于,这里是输入一个类别之后在每一时刻 输出一个字母。循环预测字符以形成语言通常也被称为“语言模型”。(也可以将字符换成单词或更高级的结构进行这一过程)

二.准备数据

 测试os函数功能:

import os

filename="data/names\Arabic.txt"
#用于获取指定路径中的基本名称。此方法在内部使用os.path.split()方法将指定路径分为一对(头,尾)。
# os.path.basename()方法将指定的路径拆分为后返回尾部(头,尾)对。
print(os.path.basename(filename))
#将路径的文件名和后缀名分割。其中文件名只是名称。
print(os.path.splitext(os.path.basename(filename)))
print(os.path.splitext(os.path.basename(filename))[0])

输出:

Arabic.txt
('Arabic', '.txt')
Arabic

***************************************************************************************************

数据预处理代码:

点击这里下载数据并将其解压到当前文件夹。

有一些纯文本文件data/names/[Language].txt,它们的每行都有一个名字。 我们按行将文本按行分割得到一个数组,将Unicode编码转化为ASCII编码,最终得到{language: [names ...]}格式存储的字典变量。

dataPreprocessing.py:

from __future__ import unicode_literals, print_function, division
from io import open
import glob
import os
import unicodedata
import string

class DataPreprocessing:
    def __init__(self):
        self.all_letters = string.ascii_letters + " .,;'-"  # 注意还有空格
        print('string.ascii_letters:', string.ascii_letters)  # 大小写的26个字母
        print('all_letters:', self.all_letters)
        self.n_letters = len(self.all_letters) + 1  # Plus EOS marker
        print('总的字符数量:', self.n_letters)

    def findFiles(self,path):
        # glob.glob返回符合匹配条件的所有文件的路径,即路径中可以用正则表达式
        return glob.glob(path)

    # 将Unicode字符串转换为纯ASCII, 感谢https://stackoverflow.com/a/518232/2809427
    def unicodeToAscii(self,s):
        return ''.join(
            c for c in unicodedata.normalize('NFD', s)
            if unicodedata.category(c) != 'Mn'
            and c in self.all_letters
        )

    # 读取文件并分成几行
    def readLines(self,filename):
        # strip()返回删除前导和尾随空格的字符串副本
        lines = open(filename, encoding='utf-8').read().strip().split('\n')
        return [self.unicodeToAscii(line) for line in lines]

    def processing(self):
        # 构建category_lines字典,列表中的每行是一个类别
        category_lines = {}
        all_categories = []
        for filename in self.findFiles('data/names/*.txt'):
            # print(filename) filename是一个路径
            category = os.path.splitext(os.path.basename(filename))[0]
            all_categories.append(category)
            lines = self.readLines(filename)
            category_lines[category] = lines

        n_categories = len(all_categories)

        if n_categories == 0:
            raise RuntimeError('Data not found. Make sure that you downloaded data '
                               'from https://download.pytorch.org/tutorial/data.zip and extract it to '
                               'the current directory.')

        return category_lines,all_categories,n_categories,self.all_letters,self.n_letters;


data=DataPreprocessing()
category_lines,all_categories,n_categories,all_letters,n_letters=data.processing()

# if __name__=='__main__':
#     data=DataPreprocessing()
#     '''
#     返回值一是一个字典,各个类型及其对应的所有名字
#     返回值2是一个列表,所有类型的名字
#     返回值3是类型的数量
#     '''
#     category_lines,all_categories,n_categories=data.processing()
#     print('种类数量:', n_categories, '所有的种类:', all_categories)
#     print("O'Néàl(unicode类型)转换到ASCII类型后为:", data.unicodeToAscii("O'Néàl"))

三.构造神经网络

这个神经网络比上一个RNN教程 中的网络增加了额外的类别张量参数,该参数与其他输入连接在一起。类别可以像字母一样组成 one-hot 向量构成张量输入。

我们将输出作为下一个字母是什么的可能性。采样过程中,当前输出可能性最高的字母作为下一时刻输入字母。

在组合隐藏状态和输出之后我们增加了第二个linear层o2o,使模型的性能更好。当然还有一个dropout层,参考这篇论文随机将输入部分替换为0 给出的参数(dropout=0.1)来模糊处理输入防止过拟合。 我们将它添加到网络的末端,故意添加一些混乱使采样特征增加。

网络结构图:

buildModel.py:

import torch
import torch.nn as nn

#导入数据预处理之后的相关数据
from dataPreprocessing import n_categories

#*********************************** 参考这篇文章的图 https://www.cnblogs.com/lccxqk/p/14622532.html
class RNN(nn.Module):
    # rnn = RNN(n_letters, 128, n_letters)说明有多少字符就有多少种输入情况,也就有多少种输出情况,所以最后需要一个Softmax层进行多元分类
    def __init__(self, input_size, hidden_size, output_size):
        super(RNN, self).__init__()
        self.hidden_size = hidden_size
        #其实是两层?只不过i2h和i2o其实可以看做一层,只不过传递的方向不一样
        self.i2h = nn.Linear(n_categories + input_size + hidden_size, hidden_size)
        self.i2o = nn.Linear(n_categories + input_size + hidden_size, output_size)
        self.o2o = nn.Linear(hidden_size + output_size, output_size)
        #防止过拟合
        self.dropout = nn.Dropout(0.1)
        #多元分类,# 对列做Softmax,最后得到的每行和为1;dim=0则每列和为1
        self.softmax = nn.LogSoftmax(dim=1)

    # 前向传播,三个参数都是行向量,且前俩是one-hot矩阵
    # 前向传播,三个参数都是行向量,结合这篇文章的前向传播那里的图进行分析 https://hanhan.blog.csdn.net/article/details/128062706
    # hidden就是图中的a,即向右传的激活值,
    # 一个单词的从左往右的所有字母依次进行前向传播,每次前向传播就对应图中的一列
    # 三个线性层其实是两层
    def forward(self, category, input, hidden):
        '''
        运行以下代码查看torch.cat的功能,即把这三个行向量连接起来
        category=torch.zeros(1, 3)
        print(category)
        input=torch.ones(1,2)
        print(input)
        hidden=torch.zeros(1,2)
        print(hidden)
        input_combined = torch.cat((category, input, hidden), 1)
        print(input_combined)
        '''
        input_combined = torch.cat((category, input, hidden), 1)
        #往右传
        hidden = self.i2h(input_combined)
        #往上传
        output = self.i2o(input_combined)
        output_combined = torch.cat((hidden, output), 1)
        output = self.o2o(output_combined)
        output = self.dropout(output)
        output = self.softmax(output)
        return output, hidden

    def initHidden(self):
        #行向量(2维,即一行2列的矩阵)
        return torch.zeros(1, self.hidden_size)

四.训练

myTrain.py:

import random

from torch import nn

from dataPreprocessing import category_lines,all_categories,n_categories,all_letters,n_letters
import torch
from buildModel import RNN

#**********************************************************3.1 训练准备
# 首先,构造一个可以随机获取成对训练数据(category, line)的函数。
# 列表中的随机项
def randomChoice(l):
    #某个类别里的随机的一个名字
    return l[random.randint(0, len(l) - 1)]

# 从所有类别中获取随机类别和该类别对应的一个名
def randomTrainingPair():
    #随机选一个类
    category = randomChoice(all_categories)
    # 上面选定的那个类里随机的一个名
    line = randomChoice(category_lines[category])
    return category, line

'''
对于每个时间步长(即,对于要训练单词中的每个字母),网络的输入将是“(类别,当前字母,隐藏状态)”,输出将是“(下一个字母,
下一个隐藏状态)”。因此,对于每个训练集,我们将需要类别、一组输入字母和一组输出/目标字母。

在每一个时间序列,我们使用当前字母预测下一个字母,所以训练用的字母对来自于一个单词。
例如 对于 "ABCD<EOS>",我们将创建 (“A”,“B”),(“B”,“C”),(“C”,“D”),(“D”,“EOS”))。

类别张量是一个<1 x n_categories>尺寸的one-hot张量。训练时,我们在每一个时间序列都将其提供给神经网络。
这是一种选择策略,也可选择将其作为初始隐藏状态的一部分,或者其他什么结构。
'''
# 类别的One-hot张量
def categoryTensor(category):
    #category是类别名,即一个字符串,list.index(元素值)返回对应元素的下标
    li = all_categories.index(category)
    #一行n_categories列的张量(可以看作二维矩阵)
    tensor = torch.zeros(1, n_categories)
    tensor[0][li] = 1
    #返回这个类别对应的one-hot矩阵
    return tensor

# 用于输入的从头到尾字母(不包括EOS)的one-hot矩阵,即单词的one-hot矩阵,即生成输入张量
def inputTensor(line):
    #line是一个单词
    '''
    对于张量而言,行向量其实就是个二维矩阵,所以一个三个元素的行向量就是一行3列的的2维矩阵,如下:
    tensor = torch.zeros(2, 1, 3)
    所以上面这句代码的1和3就代表一个三个元素的行向量就是一行3列的的2维矩阵
    然后那个2意思就是有俩一个三个元素的行向量就是一行3列的的2维矩阵
    综合起来看就像一个2行3列的矩阵一样,但其实是个三维的
    '''
    tensor = torch.zeros(len(line), 1, n_letters)
    #li是单词的每个组成字符对应的下标
    for li in range(len(line)):
        # 单词的每个组成字符
        letter = line[li]
        '''
        虽然是个三维矩阵,但是我们可以当作两维来看,第li行(对应第li个字母),0就对应第li行的那个行向量
        all_letters.find(letter)就代表这一行的这个字符对应的那一列
        '''
        tensor[li][0][all_letters.find(letter)] = 1
    #返回这个单词对应的one-hot矩阵
    return tensor

# 用于目标的第二个结束字母(EOS)的LongTensor,即生成输出张量
'''
下面这个函数的意思就是比如本来的的单词是book(最后还有一个结束符<EOS>没写上,因为单词长度是4),这是输入张量
然后经过下面的这个函数我们得到的目标张量为ook<EOS>,新旧张量的字符一一对应
b  o  o  k
o  o  k <EOS>
'''
def targetTensor(line):
    #all_letters.find(line[li])是字符在所有字符中对应的下标
    letter_indexes = [all_letters.find(line[li]) for li in range(1, len(line))]
    letter_indexes.append(n_letters - 1) # EOS
    return torch.LongTensor(letter_indexes)

'''
为了方便训练,我们将创建一个randomTrainingExample函数,该函数随机获取(类别,行)的对并将它们转换为所需要的(类别,输入, 目标)格式张量。
'''
# 从随机(类别,行)对中创建类别,输入和目标张量
def randomTrainingExample():
    # 随机获取一个类别和该类别的一个名字
    category, line = randomTrainingPair()
    # 类别的one-hot矩阵
    category_tensor = categoryTensor(category)
    # 输入单词的one-hot矩阵
    input_line_tensor = inputTensor(line)
    # 目标的one-hot矩阵
    target_line_tensor = targetTensor(line)
    return category_tensor, input_line_tensor, target_line_tensor

#****************************************************************3.2 训练神经网络
'''
和只使用最后一个时刻输出的分类任务相比,这次我们每一个时间序列都会进行一次预测,所以每一个时间序列我们都会计算损失。
autograd 的神奇之处在于您可以在每一步中简单地累加这些损失,并在最后反向传播。
'''
#损失函数
criterion = nn.NLLLoss()
#学习率
learning_rate = 0.0005
#我们自己写的RNN模型的实例,n_letters是所有字符个数
rnn = RNN(n_letters, 128, n_letters)

def train(category_tensor, input_line_tensor, target_line_tensor):
    '''
    from dataPreprocessing import all_letters,n_letters

    def targetTensor(line):
        #all_letters.find(line[li])是字符在所有字符中对应的下标
        letter_indexes = [all_letters.find(line[li]) for li in range(1, len(line))]
        letter_indexes.append(n_letters - 1) # EOS
        return torch.LongTensor(letter_indexes)

    print(targetTensor("apple"))
    print(targetTensor("apple").unsqueeze_(-1))
    '''
    #把上面的代码单独在一个文件执行一下理解.unsqueeze_(-1)在干嘛
    target_line_tensor.unsqueeze_(-1)
    hidden = rnn.initHidden()
    # 梯度清零
    rnn.zero_grad()
    #损失
    loss = 0
    #循环次数就是单词所含的字母个数
    '''
    tensor = torch.zeros(2, 1, 3)
    print(tensor.size(0)) 输出2
    即单词的one-hot矩阵每一行对应一个字母的one-hot
    '''
    for i in range(input_line_tensor.size(0)):
        #前向传播,三个参数都是行向量,结合这篇文章的前向传播那里的图进行分析 https://hanhan.blog.csdn.net/article/details/128062706
        #hidden就是图中的a,所以本次循环用的是上一次循环的hidden,即向右传激活值的过程;input_line_tensor[i]对应图中的x^<i>
        #一个单词的从左往右的所有字母依次进行前向传播,每次前向传播就是图中的一列
        #三个线性层其实是两层
        output, hidden = rnn(category_tensor, input_line_tensor[i], hidden)
        l = criterion(output, target_line_tensor[i])
        loss += l

    #反向传播,计算偏导
    loss.backward()

    #梯度下降
    #权重=权重-学习率*成本函数对此权重的偏导
    #训练过程和以前一样,要说的是这里没有用pytorch自带的优化器,而是用下面循环来参数更新,但是运行时会出现报警(但程序还是可以运行)
    for p in rnn.parameters():
        p.data.add_(-learning_rate, p.grad.data)

    return output, loss.item() / input_line_tensor.size(0)

# 为了跟踪训练耗费的时间,我添加一个timeSince(timestamp)函数,它返回一个人类可读的字符串:
import time
import math

def timeSince(since):
    now = time.time()
    s = now - since
    m = math.floor(s / 60)
    s -= m * 60
    return '%dm %ds' % (m, s)

#***************************************************     待训练完成,模型保存之后,将下列代码注释掉
'''
训练过程和平时一样。多次运行训练,等待几分钟,每print_every次打印当前时间和损失。
在all_losses中保留每plot_every次的平均损失,以便稍后进行绘图。
'''
#迭代十万次
n_iters = 100000
print_every = 5000
plot_every = 500
all_losses = []
total_loss = 0 # Reset every plot_every iters

start = time.time()

for iter in range(1, n_iters + 1):
    #星号的作用是将元组变为一个一个的值
    '''
    def fun():
        return 'a',1,"apple";
    print(fun()) #('a', 1, 'apple')
    print(*fun()) #a 1 apple
    '''
    output, loss = train(*randomTrainingExample())
    total_loss += loss

    if iter % print_every == 0:
        print('%s (%d %d%%) %.4f' % (timeSince(start), iter, iter / n_iters * 100, loss))

    if iter % plot_every == 0:
        #最近plot_every次的平均损失(加入到记录损失的列表)
        all_losses.append(total_loss / plot_every)
        total_loss = 0

#******************************************************* 3.3 损失数据作图
# 从all_losses得到历史损失记录,反映了神经网络的学习情况:
import matplotlib.pyplot as plt

plt.figure()
plt.plot(all_losses)
plt.show()

#******************************************************* 3.4 保存模型
torch.save(rnn.state_dict(), './model/myRNN.pth')

可以看到训练完成之后,相应目录下已经保存了模型的参数文件:

五.网络采样(预测)

我们每次给网络提供一个字母并预测下一个字母是什么,将预测到的字母继续输入,直到得到EOS字符结束循环。

  • 用输入类别、起始字母和空隐藏状态创建输入张量。

  • 用起始字母构建一个字符串变量 output_name

  • 得到最大输出长度,
      * 将当前字母传入神经网络
      * 从前一层得到下一个字母和下一个隐藏状态
      * 如果字母是EOS,在这里停止
      * 如果是一个普通的字母,添加到output_name变量并继续循环

  • 返回最终得到的名字单词

另一种策略是,不必给网络一个起始字母,而是在训练中提供一个“字符串开始”的标记,并让网络自己选择起始的字母。

predict.py:

import torch
from myTrain import categoryTensor,inputTensor
from dataPreprocessing import n_letters,all_letters
from buildModel import RNN

#***********************************************************  4.网络采样(即预测)
#我们自己写的RNN模型的实例,n_letters是所有字符个数
rnn = RNN(n_letters, 128, n_letters)
#加载已经训练好的模型参数
rnn.load_state_dict(torch.load('./model/myRNN.pth'))
#eval函数(一定用!!!)的作用请参考 https://blog.csdn.net/lgzlgz3102/article/details/115987271
rnn.eval()

max_length = 20

# 来自类别和首字母的样本
def sample(category, start_letter='A'):
    #表明当前计算不需要反向传播,使用with torch.no_grad()之后,强制后边的内容不进行计算图的构建
    #一般计算网络结果(预测)时,不需要反向传播,所以就就用with torch.no_grad()
    with torch.no_grad():  # no need to track history in sampling
        category_tensor = categoryTensor(category)
        input = inputTensor(start_letter)
        hidden = rnn.initHidden()

        output_name = start_letter

        for i in range(max_length):
            output, hidden = rnn(category_tensor, input[0], hidden)
            topv, topi = output.topk(1)
            if i==0:
                print('topv:',topv)
                print('topi',topi)
            topi = topi[0][0]
            #即topi是<EOS>的下标时,就可以结束了
            if topi == n_letters - 1:
                break
            else:
                letter = all_letters[topi]
                output_name += letter
            #上一个单元预测出的字符作为下一个单元的输入
            input = inputTensor(letter)

        return output_name

# 从一个类别和多个起始字母中获取多个样本
def samples(category, start_letters='ABC'):
    for start_letter in start_letters:
        print(sample(category, start_letter))

samples('Russian', 'RUS')

samples('German', 'GER')

samples('Spanish', 'SPA')

samples('Chinese', 'CHI')

输出:

Rovakov
Uakovakov
Shakovak
Garter
Erenger
Romer
Santer
Parez
Allan
Chang
Han
Iua

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/66407.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

openstack基本命令小结

文章目录Openstack0、进入1、查看日志日志位置日志格式举例2、CLI命令格式基本格式使用帮助3、命令文档&#xff08;常用&#xff09;4、基础组件的常用命令1、keystone查询类查看所有组件状态查看所有服务的状态查看域列表查看服务列表查看节点列表查询用户列表查询用户详细信…

用5G制造5G,中国电信打造“滨江模式”,助力电子信息制造产业升级

工业和信息化部近日印发《5G全连接工厂建设指南》&#xff0c;提出“十四五”时期&#xff0c;主要面向原材料、装备、消费品、电子等制造业&#xff0c;采矿、港口、电力等重点行业领域&#xff0c;加快5G全连接工厂建设。中国电信联合中兴通讯打造南京滨江智能工厂&#xff0…

Python第三方库之MedPy

1.MedPy简介 MedPy 是一个图像处理库和针对医学(如高维)图像处理的脚本集合&#xff0c;此处主要讨论利用该库计算常见的医学图像分割任务评价指标&#xff0c;如Dice、Jaccard、Hausdorff Distance、Sensitivity、Specificity、Positive predictive value等。 论文表格的表头…

docker部署的redis集群 添加节点(扩容)

上篇博文完成了在 docker 中部署 redis 多主多从集群&#xff1a;点这里 这篇博文说一下如何在集群基础上继续添加节点&#xff0c;也就是给集群扩容 博文中的命令出现的 111.111.111.111 均换成实际 IP 执行 创建要添加的一主一从容器 这里创建一个6377主节点和一个6378从节…

ArgoDB 5.1 正式发布:多模融合、实时分析和数据安全多重升级

Transwarp ArgoDB是星环科技自主研发的高性能分布式分析型数据库&#xff0c;在PB级数据量上提供极致的数据分析能力。ArgoDB支持标准SQL语法和分布式事务&#xff0c;提供高并发高速数据写入、复杂查询、多模分析、数据联邦、隐私计算和动态脱敏等能力。基于星环科技ArgoDB数据…

怎么自由裁剪图片大小?分享一款在线图片编辑工具

工作的时候常常需要用图片编辑工具把图片裁剪为我们想要的大小&#xff0c;但下载处理图片软件又耗费时间&#xff0c;那么有没有比较快捷的修改图片的方法呢&#xff1f;其实我们可以用在线图片处理&#xff08;在线ps 图片编辑制作工具 免费照片编辑器_压缩图&#xff09;工具…

日期插件(默认显示当前日期)---年月

方法&#xff1a;加载页面时将当前日期赋值 <!-- 选择年月--> <div class"form-group"><label class"col-sm-2 control-label is-required">时间&#xff1a;</label><button id"bin0"><< </button&g…

Nvidia 驱动安装

由于使用unreal engine editor 开发,需要安装nvidia 独显驱动,遇到各种坑,在此记录,方便自己以后再次遇到,也希望能帮助他人辟坑 系统: Ubuntu18.04 显卡:Geforce GTX 1650 UE版本:5.1.0 1. 自动安装 sudo ubuntu-drivers devices 推荐安装470 sudo ubuntu-drivers autoi…

Redis哨兵模式原理剖析,监控、选主、通知客户端你真的懂了吗?

哨兵启动后只指定了master的地址&#xff0c;要想知道整个集群中完整的拓扑关系怎么做呢&#xff1f; 哨兵每隔10秒会向每个master节点发送 info 命令&#xff0c; info 命令返回的信息中&#xff0c;包含了主从拓扑关系&#xff0c;其中包括每个slave的地址和端口号。有了这些…

[附源码]计算机毕业设计汽配管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

10. 获取操作系统版本和位数

1. linux如何查看系统版本 (1) 查看系统版本&#xff1a;uname -a (2) 查看内核版本信息&#xff1a;less /proc/version (3) 查看发行版本信息&#xff1a;less /etc/issue (4) 查看发行版详细信息&#xff1a;lsb_release -a 2. 怎么查看linux是32位还是64 系统 (1) getco…

Web3中文|以太坊创始人V神:关注技术,而不是价格

全球第二大数字货币交易所 FTX 轰然倒下&#xff0c;可以说是牵连甚广&#xff0c;不止是小资族&#xff0c;不少资深玩家都在这次事件中亏损数百、数千万美元。Solana、BlockFi等都在此次事件中受到巨大冲击。 基于BNB Chain的去中心化金融&#xff08;DeFi&#xff09;协议A…

Mac 上好用的远程桌面软件:Splashtop

市场分析表明&#xff0c; Mac电脑的市场份额正在增加 。在相关新闻中&#xff0c;全球远程桌面软件市场正在经历巨大的增长 。 远程桌面软件允许你通过互联网连接到一个特定的计算机&#xff0c;并用一个单独的设备来控制它。然后你就可以使用任何应用程序&#xff0c;访问主…

笔试强训48天——day23

文章目录一. 单选1.下面程序段的时间复杂度为&#xff08;&#xff09;2. 下列关于线性链表的叙述中&#xff0c;正确的是&#xff08; &#xff09;3. 下列描述的不是链表的优点是&#xff08; &#xff09;4. 向一个栈顶指针为h的带头结点的链栈中插入指针s所指的结点时,应执…

纺织进入“寒冬”,纺织企业利用APS生产排产加强生产管

进入11月&#xff0c;对于纺服产业链而言&#xff0c;大体“金九银十”的旺季订单已经结束。实际上&#xff0c;经历了前三季度的疲弱表现&#xff0c;市场整体已经对四季度缺乏信心。的确从整个下游行业来看&#xff0c;纺织出口形势依然严峻&#xff0c;预计11月份纺织行业也…

图像增强之灰度变换

前言 图像增强是图像处理常用最常用的方法&#xff0c; 目录前言引言为什么进行空间域增强什么是图像增强如何进行图像增强空间域增强灰度变换线性变换简单的黑白转换灰度拉伸分段线性变换非线性变换对数变换幂次变换直方图均衡引言 为什么进行空间域增强 什么是图像增强 按…

天宇优配|多家房企发布再融资预案,最牛地产股九连板

多家上市房企抢先发布再融资预案&#xff1b;氢能工业车辆产线有新进展&#xff0c;燃料电池本钱或有下降空间。 房地产板块掀涨停潮 12月5日&#xff0c;房地产板块再度走高&#xff0c;掀起涨停潮&#xff0c;阳光股份、招商积余、沙河股份、粤宏远A等涨停&#xff1b;所属地…

uView教程-骨架屏搭建 #低代码 #小程序 #uView

当小程序没有加载完时会出现一个基础的骨架效果&#xff0c; 页面加载完之后骨架会消失掉&#xff0c; 这个效果怎么做的呢&#xff1f; 今天由我来带领大家学习如何使用骨架屏&#xff0c; 在guiplan低代码开发工具中&#xff0c; 选中要添加骨架的元素&#xff0c; 比如…

Lecture1:从图像分类引出概念

目录 1.我们如何处理图像分配这个任务 2.图像分类远古方法----利用曼哈顿距离&#xff1a;L1距离 3.图像分类远古方法----利用欧几里得距离&#xff1a;L2距离 4.超参数 1.我们如何处理图像分配这个任务 我们要给计算机一张图片&#xff0c;让它识别出这是一只猫&#xff1…

【区块链 | 预言机】从零开始使用Chainlink预言机(2)- 智能合约中使用更安全的随机数-代码实战

智能合约中使用更安全的随机数(代码实战篇) Chainlink最近推出一款革命性的产品,VRF—Verifiable Random Function可验证随机数,给智能合约带来了真正安全的随机数。本文我们就来介绍一下如何在智能合约中使用VRF吧。 我们先简要介绍一下Chainlink VFR的工作流程。 首先,…