• [技术干货] ModelArts搭建中文语音识别系统【转载】
    前言1.ModelArts是什么ModelArts是面向AI开发者的一站式开发平台,提供海量数据预处理及半自动化标注、大规模分布式训练、自动化模型生成及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期AI工作流。“一站式”是指AI开发的各个环节,包括数据处理、算法开发、模型训练、模型部署都可以在ModelArts上完成。从技术上看,ModelArts底层支持各种异构计算资源,开发者可以根据需要灵活选择使用,而不需要关心底层的技术。同时,ModelArts支持Tensorflow、PyTorch、MindSpore等主流开源的AI开发框架,也支持开发者使用自研的算法框架,匹配您的使用习惯。ModelArts的理念就是让AI开发变得更简单、更方便。面向不同经验的AI开发者,提供便捷易用的使用流程。例如,面向业务开发者,不需关注模型或编码,可使用自动学习流程快速构建AI应用;面向AI初学者,不需关注模型开发,使用预置算法构建AI应用;面向AI工程师,提供多种开发环境,多种操作流程和模式,方便开发者编码扩展,快速构建模型及应用。本文介绍的内容主要分为如下几个部分:语音识别技术概述DFCNN全序列卷积神经网络介绍Transformer原理使用ModelArts快速上手训练DFCNN+Transformer模型完成中文语音识别系统的搭建一、语音识别技术概述1.语音识别概述语音识别(SpeechRecognition)是以语音为研究对象,通过语音信号处理和模式识别让机器自动识别和理解人类的语音。除了传统语音识别技术之外,基于深度学习的语音识别技术也逐渐发展起来。自动语音识别(Automatic Speech Recognition,ASR),也可以简称为语音识别。主要是将人类语音中的词汇内容转换为计算机可读的输入,一般都是可以理解的文本内容,也有可能是二进制编码或者字符序列。但是,我们一般理解的语音识别其实都是狭义的语音转文字的过程,简称语音转文本识别(SpeechToText,STT)更合适,这样就能与语音合成(TextToSpeech,TTS)对应起来。为了能够更加清晰的定义语音识别的任务,先来看一下语音识别的输入和输出都是什么。大家都知道,声音从本质是一种波,也就是声波,这种波可以作为一种信号来进行处理,所以语音识别的输入实际上就是一段随时间播放的信号序列,而输出则是一段文本序列。语音识别的输入与输出如图所示。2.语音识别的一般原理语音识别的一般原理是将语音信号转换为数字信号,然后使用机器学习算法对数字信号进行分析和处理,最终将语音转换为文本或命令。常用的语音识别算法包括隐马尔可夫模型、深度神经网络等。语音识别的原理流程是:首先,语音信号被采集并转换成数字信号。然后,数字信号被分析和处理,包括预处理、特征提取和模式匹配等步骤。最后,识别结果被输出。整个过程涉及到信号处理、机器学习、自然语言处理等多个领域的知识。原理流程图如下:3.信号处理与特征提取方法特征提取方法主要有:线性预测系数(LPC):线性预测系数是一种用于时间序列分析的方法,用于预测未来的数值。它是通过对历史数据进行线性回归分析,得出一组系数,然后利用这些系数来预测未来的数值。具体的计算方法可以参考统计学中的相关知识。LPC倒谱系数(LPCC):LPC倒谱系数是一种用于语音信号处理的技术,它可以通过对语音信号进行分析,提取出信号的特征参数,从而实现语音信号的压缩和识别等功能。具体来说,LPC倒谱系数是一组用于描述语音信号的线性预测模型参数,它可以通过对语音信号进行自相关分析和线性预测分析得到。在语音信号处理中,LPC倒谱系数被广泛应用于语音编码、语音合成、语音识别等领域。线谱对参数(LSP):线谱对分析法是一种用于分析复杂系统的方法,它可以将系统分解成多个子系统,并通过对子系统之间的相互作用进行分析,来揭示系统的行为和性质。该方法在系统工程、控制理论、信号处理等领域得到了广泛应用。共振峰率:共振峰率是指声音信号中的共振峰频率与声音信号的基频之比。在语音识别和语音合成中,共振峰率是一个重要的参数,可以用来识别和合成不同的语音音素。短时谱:短时谱分析法是一种信号处理技术,用于将信号分解成频率和时间的成分。它通过将信号分成短时间段,对每个时间段进行傅里叶变换,得到该时间段内信号的频率成分,从而得到整个信号的频率和时间成分。感知线性预测(PLP):感知线性预测是一种基于线性模型的机器学习算法,它可以用于分类和回归问题。它的基本思想是通过对输入数据进行线性组合,得到一个预测输出值,然后将这个预测输出值与真实输出值进行比较,从而不断调整线性组合的参数,使得预测输出值与真实输出值的误差最小化。Mel频率倒谱系数(MFCC):频率倒谱系数是一种信号处理中的特征参数,用于描述信号的频率变化情况。它可以通过对信号进行傅里叶变换和倒谱变换得到。3.1 MFCCMFCC提取过程如下:预加重:MFCC提取过程的预加重是指在语音信号的前端加入一个高通滤波器,以增强高频信号的能量,从而提高MFCC特征的稳定性和可靠性。预加重的滤波器通常是一个一阶高通滤波器,其传递函数为H(z)=1-αz^-1,其中α是预加重系数,通常取值为0.95。分帧:MFCC提取过程的分帧是将音频信号分成若干个固定长度的帧,通常每帧的长度为20-30毫秒,帧与帧之间有一定的重叠。然后对每一帧进行加窗处理,以减少频谱泄漏的影响。最后对每一帧进行傅里叶变换,得到其频谱信息,再通过Mel滤波器组将频谱信息转换为Mel频率下的能量分布,最后再进行离散余弦变换,得到MFCC系数。加窗:MFCC提取过程中的加窗是为了减少频谱泄漏的影响,常用的加窗函数有汉明窗、海宁窗等。加窗后,信号在频域上的能量分布更加集中,可以更准确地提取出MFCC特征。快速傅里叶变换(FFT):MFCC提取过程中的快速傅里叶变换是用来将语音信号转换为频域特征的一种方法。它可以通过将语音信号分成短时窗口,并对每个窗口进行傅里叶变换来实现。这个过程可以使用快速傅里叶变换算法来加速计算。通过三角带通滤器得到Mel频谱:MFCC提取过程中的三角带通滤器是一种用于将音频信号转换为频谱图的滤波器。它可以将音频信号分成不同的频带,并且对每个频带进行加权,以便更好地反映人类听觉系统的特性。三角带通滤波器通常使用Mel刻度来划分频带,以便更好地模拟人类听觉系统的响应。倒谱分析(取对数,做逆变换):MFCC提取过程中的倒谱分析是将音频信号转换为倒谱系数的过程。它首先将音频信号分帧,然后对每一帧进行加窗处理,接着进行傅里叶变换,得到频谱图。然后对频谱图进行对数化处理,再进行离散余弦变换,得到倒谱系数。倒谱系数是MFCC特征的一部分,用于表示音频信号的频率特征。4.基于深度学习的声学模型DNN-HMMDNN-HMM主要是用DNN模型代替原来的GMM模型,对每一个状态进行建模,DNN带来的好处是不再需要对语音数据分布进行假设,将相邻的语音帧拼接又包含了语音的时序结构信息,使得对于状态的分类概率有了明显提升,同时DNN还具有强大环境学习能力,可以提升对噪声和口音的鲁棒性。HMM用来描述语音信号的动态变化,DNN则是用来估计观察特征的概率。在给定声学观察特征的条件下,我们可以用DNN的每个输出节点来估计HMM某个状态的后验概率。由于DNN-HMM训练成本不高而且相对较高的识别概率,所以即使是到现在在语音识别领域仍然是较为常用的声学模型。二、DFCNN全序列卷积神经网络介绍DFCNN的全称叫作全序列卷积神经网络(Deep Fully Convolutional Neural Network),是由国内语音识别领域领头羊科大讯飞于2016年提出的一种语音识别框架。DFCNN先对时域的语音信号进行傅里叶变换得到语音的语谱图,DFCNN直接将一句语音转化成一张图像作为输入,输出单元则直接与最终的识别结果(例如,音节或者汉字)相对应。DFCNN的结构中把时间和频率作为图像的两个维度,通过较多的卷积层和池化(pooling)层的组合,实现对整句语音的建模。三、Transformer原理Transformer的本质上是一个Encoder-Decoder的结构,Transformer是一个利用注意力机制来提高模型训练速度的模型,用于处理序列到序列的任务,如机器翻译、文本摘要、语音识别等。它由编码器和解码器两部分组成,每个部分都由多个层级的自注意力和前馈神经网络组成。编码器将输入序列映射到一组隐藏表示,解码器则使用这些表示来生成输出序列。Transformer 的自注意力机制可以同时考虑输入序列中的所有位置,从而更好地捕捉序列中的长距离依赖关系。四、使用ModelArts快速上手训练DFCNN+Transformer模型完成中文语音识别系统的搭建1.ModelArts,致力打造行业AI落地首选平台ModelArts是华为云推出的一款人工智能开发平台,旨在为企业和开发者提供全面的AI解决方案和服务,包括数据管理、模型训练、模型部署等。它支持多种框架和算法,如TensorFlow、PyTorch、Caffe等,可以帮助用户快速构建和部署AI应用。ModelArts的流程主要有:数据处理、算法开发、模型训练、模型管理、模型部署。2.算法开发:面向四类开发人员提供AI开发工具ModelArts提供了面向四类开发人员的AI开发工具,包括AI应用开发者、AI算法工程师、AI研究员和AI应用运维。3.DFCNN+Transformer模型完成中文语音识别系统的搭建DFCNN+Transformer模型完成中文语音识别系统的搭建的步骤主要有:准备源代码和数据,从obs链接下载解压下载数据集THCHS-30,数据预处理加载需要的python库声学模型DFCNN介绍建立DFCNN声学模型获取数据类声学模型训练语言模型Transformer的介绍多头注意力的实现语言模型训练模型测试3.1 系统环境搭建1、打开基于ModelArts搭建中文语音识别系统的源码并点击运行Run in ModelArts:cid:link_02、点击切换资源至此环境都准备完成3.2 DFCNN+Transformer模型完成中文语音识别系统的搭建的步骤3.2.1 提取源码数据准备案例所需的源代码和数据,相关资源已经保存在 OBS 中,我们通过 ModelArts SDK 将资源下载到本地。import osimport subprocessfrom modelarts.session import Sessionsession = Session()if session.region_name == 'cn-north-1': bucket_path = 'modelarts-labs/notebook/DL_speech_recognition/speech_recognition.tar.gz'elif session.region_name == 'cn-north-4': bucket_path = 'modelarts-labs-bj4/notebook/DL_speech_recognition/speech_recognition.tar.gz'else: print("请更换地区到北京一或北京四")if not os.path.exists('speech_recognition'): session.download_data(bucket_path=bucket_path, path='./speech_recognition.tar.gz') subprocess.run(['tar xf ./speech_recognition.tar.gz;rm ./speech_recognition.tar.gz'], stdout=subprocess.PIPE, shell=True, check=True)3.2.2 提取数据集THCHS30是一个经典的中文语音数据集,包含了1万余条语音文件,大约40小时的中文语音数据,内容以新闻文章诗句为主,全部为女声。THCHS-30是在安静的办公室环境下,通过单个碳粒麦克风录取的,采样频率16kHz,采样大小16bits,录制对象为普通话流利的女性大学生。with open('./speech_recognition/data.txt',"r", encoding='UTF-8') as f: #设置文件对象 f_ = f.readlines() for i in range(10): for j in range(3): print(f_[i].split('\t')[j]) print('语音总数量:',len(f_),'\n')3.2.3 加载需要的python库import osimport numpy as npimport scipy.io.wavfile as wavimport matplotlib.pyplot as pltimport tensorflow as tf3.2.4 建立DFCNN声学模型本实践采用的 DFCNN 与连接时序分类模型(CTC,connectionist temporal classification)方案结合,以实现整个模型的端到端声学模型训练,且其包含的池化层等特殊结构可以使得以上端到端训练变得更加稳定。与传统的声学模型训练相比,采用CTC作为损失函数的声学模型训练,是一种完全端到端的声学模型训练,不需要预先对数据做对齐,只需要一个输入序列和一个输出序列即可以训练。这样就不需要对数据对齐和一一标注,并且CTC直接输出序列预测的概率,不需要外部的后处理。import kerasfrom keras.layers import Input, Conv2D, BatchNormalization, MaxPooling2Dfrom keras.layers import Reshape, Dense, Dropout, Lambdafrom keras.optimizers import Adamfrom keras import backend as Kfrom keras.models import Modelfrom tensorflow.contrib.training import HParams#定义卷积层def conv2d(size): return Conv2D(size, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')#定义BN层def norm(x): return BatchNormalization(axis=-1)(x)#定义最大池化层def maxpool(x): return MaxPooling2D(pool_size=(2,2), strides=None, padding="valid")(x)#定义dense层def dense(units, activation="relu"): return Dense(units, activation=activation, use_bias=True, kernel_initializer='he_normal')#两个卷积层加一个最大池化层的组合def cnn_cell(size, x, pool=True): x = norm(conv2d(size)(x)) x = norm(conv2d(size)(x)) if pool: x = maxpool(x) return x#CTC损失函数def ctc_lambda(args): labels, y_pred, input_length, label_length = args y_pred = y_pred[:, :, :] return K.ctc_batch_cost(labels, y_pred, input_length, label_length)#组合声学模型class acoustic_model(): def __init__(self, args): self.vocab_size = args.vocab_size self.learning_rate = args.learning_rate self.is_training = args.is_training self._model_init() if self.is_training: self._ctc_init() self.opt_init() def _model_init(self): self.inputs = Input(name='the_inputs', shape=(None, 200, 1)) self.h1 = cnn_cell(32, self.inputs) self.h2 = cnn_cell(64, self.h1) self.h3 = cnn_cell(128, self.h2) self.h4 = cnn_cell(128, self.h3, pool=False) self.h5 = cnn_cell(128, self.h4, pool=False) # 200 / 8 * 128 = 3200 self.h6 = Reshape((-1, 3200))(self.h5) self.h6 = Dropout(0.2)(self.h6) self.h7 = dense(256)(self.h6) self.h7 = Dropout(0.2)(self.h7) self.outputs = dense(self.vocab_size, activation='softmax')(self.h7) self.model = Model(inputs=self.inputs, outputs=self.outputs) def _ctc_init(self): self.labels = Input(name='the_labels', shape=[None], dtype='float32') self.input_length = Input(name='input_length', shape=[1], dtype='int64') self.label_length = Input(name='label_length', shape=[1], dtype='int64') self.loss_out = Lambda(ctc_lambda, output_shape=(1,), name='ctc')\ ([self.labels, self.outputs, self.input_length, self.label_length]) self.ctc_model = Model(inputs=[self.labels, self.inputs, self.input_length, self.label_length], outputs=self.loss_out) def opt_init(self): opt = Adam(lr = self.learning_rate, beta_1 = 0.9, beta_2 = 0.999, decay = 0.01, epsilon = 10e-8) self.ctc_model.compile(loss={'ctc': lambda y_true, output: output}, optimizer=opt)def acoustic_model_hparams(): params = HParams( vocab_size = 50, learning_rate = 0.0008, is_training = True) return paramsprint("打印声学模型结构")acoustic_model_args = acoustic_model_hparams() acoustic = acoustic_model(acoustic_model_args)acoustic.ctc_model.summary()3.2.5 获取数据类from scipy.fftpack import fft# 获取信号的时频图def compute_fbank(file): x=np.linspace(0, 400 - 1, 400, dtype = np.int64) w = 0.54 - 0.46 * np.cos(2 * np.pi * (x) / (400 - 1) ) fs, wavsignal = wav.read(file) time_window = 25 window_length = fs / 1000 * time_window wav_arr = np.array(wavsignal) wav_length = len(wavsignal) range0_end = int(len(wavsignal)/fs*1000 - time_window) // 10 data_input = np.zeros((range0_end, 200), dtype = np.float) data_line = np.zeros((1, 400), dtype = np.float) for i in range(0, range0_end): p_start = i * 160 p_end = p_start + 400 data_line = wav_arr[p_start:p_end] data_line = data_line * w data_line = np.abs(fft(data_line)) data_input[i]=data_line[0:200] data_input = np.log(data_input + 1) return data_inputclass get_data(): def __init__(self, args): self.data_path = args.data_path self.data_length = args.data_length self.batch_size = args.batch_size self.source_init() def source_init(self): self.wav_lst = [] self.pin_lst = [] self.han_lst = [] with open('speech_recognition/data.txt', 'r', encoding='utf8') as f: data = f.readlines() for line in data: wav_file, pin, han = line.split('\t') self.wav_lst.append(wav_file) self.pin_lst.append(pin.split(' ')) self.han_lst.append(han.strip('\n')) if self.data_length: self.wav_lst = self.wav_lst[:self.data_length] self.pin_lst = self.pin_lst[:self.data_length] self.han_lst = self.han_lst[:self.data_length] self.acoustic_vocab = self.acoustic_model_vocab(self.pin_lst) self.pin_vocab = self.language_model_pin_vocab(self.pin_lst) self.han_vocab = self.language_model_han_vocab(self.han_lst) def get_acoustic_model_batch(self): _list = [i for i in range(len(self.wav_lst))] while 1: for i in range(len(self.wav_lst) // self.batch_size): wav_data_lst = [] label_data_lst = [] begin = i * self.batch_size end = begin + self.batch_size sub_list = _list[begin:end] for index in sub_list: fbank = compute_fbank(self.data_path + self.wav_lst[index]) pad_fbank = np.zeros((fbank.shape[0] // 8 * 8 + 8, fbank.shape[1])) pad_fbank[:fbank.shape[0], :] = fbank label = self.pin2id(self.pin_lst[index], self.acoustic_vocab) label_ctc_len = self.ctc_len(label) if pad_fbank.shape[0] // 8 >= label_ctc_len: wav_data_lst.append(pad_fbank) label_data_lst.append(label) pad_wav_data, input_length = self.wav_padding(wav_data_lst) pad_label_data, label_length = self.label_padding(label_data_lst) inputs = {'the_inputs': pad_wav_data, 'the_labels': pad_label_data, 'input_length': input_length, 'label_length': label_length, } outputs = {'ctc': np.zeros(pad_wav_data.shape[0], )} yield inputs, outputs def get_language_model_batch(self): batch_num = len(self.pin_lst) // self.batch_size for k in range(batch_num): begin = k * self.batch_size end = begin + self.batch_size input_batch = self.pin_lst[begin:end] label_batch = self.han_lst[begin:end] max_len = max([len(line) for line in input_batch]) input_batch = np.array( [self.pin2id(line, self.pin_vocab) + [0] * (max_len - len(line)) for line in input_batch]) label_batch = np.array( [self.han2id(line, self.han_vocab) + [0] * (max_len - len(line)) for line in label_batch]) yield input_batch, label_batch def pin2id(self, line, vocab): return [vocab.index(pin) for pin in line] def han2id(self, line, vocab): return [vocab.index(han) for han in line] def wav_padding(self, wav_data_lst): wav_lens = [len(data) for data in wav_data_lst] wav_max_len = max(wav_lens) wav_lens = np.array([leng // 8 for leng in wav_lens]) new_wav_data_lst = np.zeros((len(wav_data_lst), wav_max_len, 200, 1)) for i in range(len(wav_data_lst)): new_wav_data_lst[i, :wav_data_lst[i].shape[0], :, 0] = wav_data_lst[i] return new_wav_data_lst, wav_lens def label_padding(self, label_data_lst): label_lens = np.array([len(label) for label in label_data_lst]) max_label_len = max(label_lens) new_label_data_lst = np.zeros((len(label_data_lst), max_label_len)) for i in range(len(label_data_lst)): new_label_data_lst[i][:len(label_data_lst[i])] = label_data_lst[i] return new_label_data_lst, label_lens def acoustic_model_vocab(self, data): vocab = [] for line in data: line = line for pin in line: if pin not in vocab: vocab.append(pin) vocab.append('_') return vocab def language_model_pin_vocab(self, data): vocab = ['<PAD>'] for line in data: for pin in line: if pin not in vocab: vocab.append(pin) return vocab def language_model_han_vocab(self, data): vocab = ['<PAD>'] for line in data: line = ''.join(line.split(' ')) for han in line: if han not in vocab: vocab.append(han) return vocab def ctc_len(self, label): add_len = 0 label_len = len(label) for i in range(label_len - 1): if label[i] == label[i + 1]: add_len += 1 return label_len + add_len3.2.6 声学模型训练为了本示例演示效果,参数batch_size在此仅设置为1,参数data_length在此仅设置为20若进行完整训练,则应注释data_args.data_length = 20,并调高batch_sizedef data_hparams(): params = HParams( data_path = './speech_recognition/data/', #d数据路径 batch_size = 1, #批尺寸 data_length = None, #长度 ) return paramsdata_args = data_hparams()data_args.data_length = 20 # 重新训练需要注释该行train_data = get_data(data_args)acoustic_model_args = acoustic_model_hparams()acoustic_model_args.vocab_size = len(train_data.acoustic_vocab)acoustic = acoustic_model(acoustic_model_args)print('声学模型参数:')print(acoustic_model_args)if os.path.exists('/speech_recognition/acoustic_model/model.h5'): print('加载声学模型') acoustic.ctc_model.load_weights('./speech_recognition/acoustic_model/model.h5')epochs = 20batch_num = len(train_data.wav_lst) // train_data.batch_sizeprint("训练轮数epochs:",epochs)print("批数量batch_num:",batch_num)print("开始训练!")for k in range(epochs): print('第', k+1, '个epoch') batch = train_data.get_acoustic_model_batch() acoustic.ctc_model.fit_generator(batch, steps_per_epoch=batch_num, epochs=1)print("\n训练完成,保存模型")acoustic.ctc_model.save_weights('./speech_recognition/acoustic_model/model.h5')3.2.7 语言模型建模Transformer 是完全基于注意力机制(attention mechanism)的网络框架,attention 来自于论文《attention is all you need》。 一个序列每个字符对其上下文字符的影响作用都不同,每个字对序列的语义信息贡献也不同,可以通过一种机制将原输入序列中字符向量通过加权融合序列中所有字符的语义向量信息来产生新的向量,即增强了原语义信息。1、定义归一化 normalize层def normalize(inputs, epsilon = 1e-8, scope="ln", reuse=None): with tf.variable_scope(scope, reuse=reuse): inputs_shape = inputs.get_shape() params_shape = inputs_shape[-1:] mean, variance = tf.nn.moments(inputs, [-1], keep_dims=True) beta= tf.Variable(tf.zeros(params_shape)) gamma = tf.Variable(tf.ones(params_shape)) normalized = (inputs - mean) / ( (variance + epsilon) ** (.5) ) outputs = gamma * normalized + beta return outputs2、定义嵌入层 embeddingdef embedding(inputs, vocab_size, num_units, zero_pad=True, scale=True, scope="embedding", reuse=None): with tf.variable_scope(scope, reuse=reuse): lookup_table = tf.get_variable('lookup_table', dtype=tf.float32, shape=[vocab_size, num_units], initializer=tf.contrib.layers.xavier_initializer()) if zero_pad: lookup_table = tf.concat((tf.zeros(shape=[1, num_units]), lookup_table[1:, :]), 0) outputs = tf.nn.embedding_lookup(lookup_table, inputs) if scale: outputs = outputs * (num_units ** 0.5) return outputs3.2.8 多头注意力层要了解多头注意力层,首先要知道点乘注意力(Scaled Dot-Product Attention)。Attention 有三个输入(querys,keys,values),有一个输出。选择三个输入是考虑到模型的通用性,输出是所有 value 的加权求和。value 的权重来自于 query 和 keys 的乘积,经过一个 softmax 之后得到。1、定义 multi-head attention层def multihead_attention(emb, queries, keys, num_units=None, num_heads=8, dropout_rate=0, is_training=True, causality=False, scope="multihead_attention", reuse=None): with tf.variable_scope(scope, reuse=reuse): if num_units is None: num_units = queries.get_shape().as_list[-1] Q = tf.layers.dense(queries, num_units, activation=tf.nn.relu) # (N, T_q, C) K = tf.layers.dense(keys, num_units, activation=tf.nn.relu) # (N, T_k, C) V = tf.layers.dense(keys, num_units, activation=tf.nn.relu) # (N, T_k, C) Q_ = tf.concat(tf.split(Q, num_heads, axis=2), axis=0) # (h*N, T_q, C/h) K_ = tf.concat(tf.split(K, num_heads, axis=2), axis=0) # (h*N, T_k, C/h) V_ = tf.concat(tf.split(V, num_heads, axis=2), axis=0) # (h*N, T_k, C/h) outputs = tf.matmul(Q_, tf.transpose(K_, [0, 2, 1])) # (h*N, T_q, T_k) outputs = outputs / (K_.get_shape().as_list()[-1] ** 0.5) key_masks = tf.sign(tf.abs(tf.reduce_sum(emb, axis=-1))) # (N, T_k) key_masks = tf.tile(key_masks, [num_heads, 1]) # (h*N, T_k) key_masks = tf.tile(tf.expand_dims(key_masks, 1), [1, tf.shape(queries)[1], 1]) # (h*N, T_q, T_k) paddings = tf.ones_like(outputs)*(-2**32+1) outputs = tf.where(tf.equal(key_masks, 0), paddings, outputs) # (h*N, T_q, T_k) if causality: diag_vals = tf.ones_like(outputs[0, :, :]) # (T_q, T_k) tril = tf.contrib.linalg.LinearOperatorTriL(diag_vals).to_dense() # (T_q, T_k) masks = tf.tile(tf.expand_dims(tril, 0), [tf.shape(outputs)[0], 1, 1]) # (h*N, T_q, T_k) paddings = tf.ones_like(masks)*(-2**32+1) outputs = tf.where(tf.equal(masks, 0), paddings, outputs) # (h*N, T_q, T_k) outputs = tf.nn.softmax(outputs) # (h*N, T_q, T_k) query_masks = tf.sign(tf.abs(tf.reduce_sum(emb, axis=-1))) # (N, T_q) query_masks = tf.tile(query_masks, [num_heads, 1]) # (h*N, T_q) query_masks = tf.tile(tf.expand_dims(query_masks, -1), [1, 1, tf.shape(keys)[1]]) # (h*N, T_q, T_k) outputs *= query_masks # broadcasting. (N, T_q, C) outputs = tf.layers.dropout(outputs, rate=dropout_rate, training=tf.convert_to_tensor(is_training)) outputs = tf.matmul(outputs, V_) # ( h*N, T_q, C/h) outputs = tf.concat(tf.split(outputs, num_heads, axis=0), axis=2 ) # (N, T_q, C) outputs += queries outputs = normalize(outputs) # (N, T_q, C) return outputs2、定义 feedforward层def feedforward(inputs, num_units=[2048, 512], scope="multihead_attention", reuse=None): with tf.variable_scope(scope, reuse=reuse): params = {"inputs": inputs, "filters": num_units[0], "kernel_size": 1, "activation": tf.nn.relu, "use_bias": True} outputs = tf.layers.conv1d(**params) params = {"inputs": outputs, "filters": num_units[1], "kernel_size": 1, "activation": None, "use_bias": True} outputs = tf.layers.conv1d(**params) outputs += inputs outputs = normalize(outputs) return outputs3、定义 label_smoothing层def label_smoothing(inputs, epsilon=0.1): K = inputs.get_shape().as_list()[-1] # number of channels return ((1-epsilon) * inputs) + (epsilon / K)#组合语言模型class language_model(): def __init__(self, arg): self.graph = tf.Graph() with self.graph.as_default(): self.is_training = arg.is_training self.hidden_units = arg.hidden_units self.input_vocab_size = arg.input_vocab_size self.label_vocab_size = arg.label_vocab_size self.num_heads = arg.num_heads self.num_blocks = arg.num_blocks self.max_length = arg.max_length self.learning_rate = arg.learning_rate self.dropout_rate = arg.dropout_rate self.x = tf.placeholder(tf.int32, shape=(None, None)) self.y = tf.placeholder(tf.int32, shape=(None, None)) self.emb = embedding(self.x, vocab_size=self.input_vocab_size, num_units=self.hidden_units, scale=True, scope="enc_embed") self.enc = self.emb + embedding(tf.tile(tf.expand_dims(tf.range(tf.shape(self.x)[1]), 0), [tf.shape(self.x)[0], 1]), vocab_size=self.max_length,num_units=self.hidden_units, zero_pad=False, scale=False,scope="enc_pe") self.enc = tf.layers.dropout(self.enc, rate=self.dropout_rate, training=tf.convert_to_tensor(self.is_training)) for i in range(self.num_blocks): with tf.variable_scope("num_blocks_{}".format(i)): self.enc = multihead_attention(emb = self.emb, queries=self.enc, keys=self.enc, num_units=self.hidden_units, num_heads=self.num_heads, dropout_rate=self.dropout_rate, is_training=self.is_training, causality=False) self.outputs = feedforward(self.enc, num_units=[4*self.hidden_units, self.hidden_units]) self.logits = tf.layers.dense(self.outputs, self.label_vocab_size) self.preds = tf.to_int32(tf.argmax(self.logits, axis=-1)) self.istarget = tf.to_float(tf.not_equal(self.y, 0)) self.acc = tf.reduce_sum(tf.to_float(tf.equal(self.preds, self.y))*self.istarget)/ (tf.reduce_sum(self.istarget)) tf.summary.scalar('acc', self.acc) if self.is_training: self.y_smoothed = label_smoothing(tf.one_hot(self.y, depth=self.label_vocab_size)) self.loss = tf.nn.softmax_cross_entropy_with_logits_v2(logits=self.logits, labels=self.y_smoothed) self.mean_loss = tf.reduce_sum(self.loss*self.istarget) / (tf.reduce_sum(self.istarget)) self.global_step = tf.Variable(0, name='global_step', trainable=False) self.optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate, beta1=0.9, beta2=0.98, epsilon=1e-8) self.train_op = self.optimizer.minimize(self.mean_loss, global_step=self.global_step) tf.summary.scalar('mean_loss', self.mean_loss) self.merged = tf.summary.merge_all()print('语音模型建立完成!')3.2.9 语言模型训练1、准备训练参数及数据def language_model_hparams(): params = HParams( num_heads = 8, num_blocks = 6, input_vocab_size = 50, label_vocab_size = 50, max_length = 100, hidden_units = 512, dropout_rate = 0.2, learning_rate = 0.0003, is_training = True) return paramslanguage_model_args = language_model_hparams()language_model_args.input_vocab_size = len(train_data.pin_vocab)language_model_args.label_vocab_size = len(train_data.han_vocab)language = language_model(language_model_args)print('语言模型参数:')print(language_model_args)2、训练语言模型epochs = 20print("训练轮数epochs:",epochs)print("\n开始训练!")with language.graph.as_default(): saver =tf.train.Saver()with tf.Session(graph=language.graph) as sess: merged = tf.summary.merge_all() sess.run(tf.global_variables_initializer()) if os.path.exists('/speech_recognition/language_model/model.meta'): print('加载语言模型') saver.restore(sess, './speech_recognition/language_model/model') writer = tf.summary.FileWriter('./speech_recognition/language_model/tensorboard', tf.get_default_graph()) for k in range(epochs): total_loss = 0 batch = train_data.get_language_model_batch() for i in range(batch_num): input_batch, label_batch = next(batch) feed = {language.x: input_batch, language.y: label_batch} cost,_ = sess.run([language.mean_loss,language.train_op], feed_dict=feed) total_loss += cost if (k * batch_num + i) % 10 == 0: rs=sess.run(merged, feed_dict=feed) writer.add_summary(rs, k * batch_num + i) print('第', k+1, '个 epoch', ': average loss = ', total_loss/batch_num) print("\n训练完成,保存模型") saver.save(sess, './speech_recognition/language_model/model') writer.close()3.2.10 模型测试1、准备解码所需字典,需和训练一致,也可以将字典保存到本地,直接进行读取data_args = data_hparams()data_args.data_length = 20 # 重新训练需要注释该行train_data = get_data(data_args)2、准备测试所需数据, 不必和训练数据一致。test_data = get_data(data_args)acoustic_model_batch = test_data.get_acoustic_model_batch()language_model_batch = test_data.get_language_model_batch()3、加载训练好的声学模型acoustic_model_args = acoustic_model_hparams()acoustic_model_args.vocab_size = len(train_data.acoustic_vocab)acoustic = acoustic_model(acoustic_model_args)acoustic.ctc_model.summary()acoustic.ctc_model.load_weights('./speech_recognition/acoustic_model/model.h5')print('声学模型参数:')print(acoustic_model_args)print('\n加载声学模型完成!')4、加载训练好的语言模型language_model_args = language_model_hparams()language_model_args.input_vocab_size = len(train_data.pin_vocab)language_model_args.label_vocab_size = len(train_data.han_vocab)language = language_model(language_model_args)sess = tf.Session(graph=language.graph)with language.graph.as_default(): saver =tf.train.Saver()with sess.as_default(): saver.restore(sess, './speech_recognition/language_model/model')print('语言模型参数:')print(language_model_args)print('\n加载语言模型完成!')5、定义解码器def decode_ctc(num_result, num2word): result = num_result[:, :, :] in_len = np.zeros((1), dtype = np.int32) in_len[0] = result.shape[1] t = K.ctc_decode(result, in_len, greedy = True, beam_width=10, top_paths=1) v = K.get_value(t[0][0]) v = v[0] text = [] for i in v: text.append(num2word[i]) return v, text6、测试语音识别​for i in range(10): print('\n示例', i+1) # 载入训练好的模型,并进行识别 inputs, outputs = next(acoustic_model_batch) x = inputs['the_inputs'] y = inputs['the_labels'][0] result = acoustic.model.predict(x, steps=1) # 将数字结果转化为文本结果 _, text = decode_ctc(result, train_data.acoustic_vocab) text = ' '.join(text) print('原文拼音:', ' '.join([train_data.acoustic_vocab[int(i)] for i in y])) print('识别结果:', text) with sess.as_default(): try: _, y = next(language_model_batch) text = text.strip('\n').split(' ') x = np.array([train_data.pin_vocab.index(pin) for pin in text]) x = x.reshape(1, -1) preds = sess.run(language.preds, {language.x: x}) got = ''.join(train_data.han_vocab[idx] for idx in preds[0]) print('原文汉字:', ''.join(train_data.han_vocab[idx] for idx in y[0])) print('识别结果:', got) except StopIteration: breaksess.close()​可以看到识别结果,准确率还是很高的总结语音识别系统是一种人工智能技术,它可以将人类语音转换为计算机可识别的文本或指令。这种技术可以应用于语音助手、智能家居、语音搜索、语音翻译等领域。语音识别系统通常包括语音信号采集、信号预处理、特征提取、模型训练和识别等步骤。其中,模型训练是关键的一步,它需要使用大量的语音数据进行训练,以提高识别准确率。目前,市面上已经有很多成熟的语音识别系统,例如百度语音、阿里云语音、微软小冰等。ModelArts进行模型训练的优势包括:高效的分布式训练、自动化的超参数调优、灵活的模型管理、安全的数据隔离和多样的算法支持等。此外,ModelArts还提供了丰富的数据预处理和模型评估功能,帮助用户更快速、更准确地完成模型训练和部署。基于ModelArts搭建中文语音识别系统的优势在于其高准确率和稳定性,同时支持多种语言和方言,具有较好的适应性和可扩展性。此外,该系统还具备较高的实时性和处理速度,能够满足各种语音识别场景的需求转载原文链接:【愚公系列】华为云系列之ModelArts搭建中文语音识别系统_dfcnn+transformer-CSDN博客
  • [其他] 浅谈机器学习工具
    了解一些该领域的常用工具开源工具Python – 由于其易用性,灵活性和开源特性,Python是当今行业数据科学中最主要的语言之一。它已经在ML社区中迅速普及并被广泛接受。 R – 它是数据科学中另一种非常常用且受人尊敬的语言。R有一个蓬勃发展且被极大支持的社区,附带了许多软件包和库,支持大多数的机器学习任务。Apache Spark – Spark由加州大学伯克利分校于2010年开源,此后已成为最大的大数据社区之一。它被称为大数据分析的“瑞士军刀”,因为它具有多种优势,例如灵活性、速度、计算能力等。Julia – 它是一种即将到来的语言,被捧为Python的继承者。目前它仍处于起步阶段,观察其在未来的表现将会是一件有趣的事。Jupyter Notebooks – 这些笔记本广泛用于Python编程。尽管它主要用于Python,但它也支持其他语言,Julia,R等。收费工具SAS – 这是一个非常受欢迎且功能强大的工具。在银行和金融部门中被普遍使用。它的使用在美国运通,摩根大通,西格玛,苏格兰皇家银行等私人组织中占有很高的份额。SPSS – SPSS是“社会科学统计软件包”的缩写,在2009年被IBM收购。它提供高级统计分析、庞大的机器学习算法库、文本分析等。Matlab – Matlab在组织机构的领域里确实被低估了,但在学术界和研究部门中得到了广泛的使用。最近相较于Python,R和SAS,Matlab已经阵地失守,但是大学(尤其在美国)仍在使用Matlab教授许多本科课程。
  • [技术干货] ModelArts:开启人工智能建模新篇章
    随着人工智能技术的飞速发展,数据建模已经成为众多企业和研究机构的核心工作。在这个过程中,ModelArts作为一款强大的人工智能建模平台,正逐渐成为业界的焦点。本文将深入探讨ModelArts的背景、功能、应用场景以及未来发展,揭示其在人工智能建模领域的独特价值和广阔前景。一、ModelArts的背景与功能ModelArts是由阿里巴巴集团推出的一款人工智能建模平台。它致力于提供一站式的模型开发、训练、部署和运营服务,让用户更快速、更高效地构建和部署人工智能模型。ModelArts具有以下核心功能:模型开发:提供丰富的算法库和工具,支持用户快速构建各种类型的人工智能模型。 模型训练:支持大规模分布式训练,提高模型训练效率和准确性。 模型评估:通过多种评估指标对模型进行全面评估,确保模型的有效性和性能。 模型部署:将训练好的模型部署到生产环境中,快速响应业务需求。 模型监控:实时监控模型运行状态,及时发现和解决潜在问题。 模型优化:根据模型运行数据,自动或手动调整模型参数,提高模型性能。二、ModelArts的应用场景ModelArts在众多领域都有广泛的应用,如金融、医疗、电商、智能客服等。以下是一些典型的应用场景:金融风控:通过ModelArts构建风险评估模型,对金融交易进行实时监控,预防和发现潜在的风险行为。 医疗影像分析:利用ModelArts构建医学影像分析模型,辅助医生进行疾病诊断和治疗方案制定。 电商推荐系统:通过ModelArts构建个性化推荐模型,提高电商平台的用户转化率和购物体验。 智能客服:利用ModelArts构建智能客服机器人,自动回答用户咨询,提升客户服务效率和用户满意度。 语音识别与合成:通过ModelArts构建语音识别和语音合成模型,实现语音交互和智能语音助手等功能。 自然语言处理:利用ModelArts构建文本分类、情感分析、机器翻译等NLP模型,提升文本处理和分析能力。 智能制造:在工业领域中,ModelArts可应用于设备故障预测、工艺优化等方面,提高生产效率和降低成本。 智慧城市:通过ModelArts构建城市管理相关的各类人工智能模型,助力智慧城市建设和管理。 教育领域:利用ModelArts构建个性化教学和学习模型,实现智能化教育和教学管理。三、ModelArts的未来发展随着技术的不断进步和市场需求的变化,我们相信ModelArts未来将在以下几个方面得到进一步发展:自动化和智能化:借助深度学习和强化学习等技术,ModelArts将进一步提升自动化和智能化水平,降低用户的使用门槛和技术难度。 数据安全与隐私保护:在保障数据安全和用户隐私方面,ModelArts将采取更加严格的安全措施和技术手段,确保数据和隐私的安全可靠。 可解释性与伦理规范:为了更好地满足监管和伦理要求,ModelArts将加强模型的解释性和公平性,制定更加完善的伦理规范和审核机制。 生态合作与共赢:ModelArts将积极构建开放合作的生态圈,与各类合作伙伴共同推动人工智能技术的发展和应用。 全球化和本地化:为了更好地服务全球用户,ModelArts将加强产品的全球化和本地化能力,提供更加符合不同国家和地区用户需求的产品和服务。
  • [技术干货] 华为云HiLens Kit试用测评—全栈全场景的人工智能【转】
    一、What根据官网的介绍,华为云HiLens,由具备AI推理能力的摄像头(如华为云多模态人工智能开发套件HiLens Kit)和云上开发平台组成,提供一站式技能开发、设备管理、数据管理、技能市场等,帮助用户开发AI技能并将其下发到端侧设备。 华为云HiLens首批发布了5类应用场景,包含家庭、车载、园区、商超和其他等。涉及了25+的技能集,主要包含人脸/人形检测、人脸属性检测、异常声音检测、疲劳驾驶、人脸对比、车牌识别、入侵检测、人流热地图等。HiLens关键特性有以下四点:关键能力1:一站式Skill开发服务,快速定制行业应用;关键能力2:端侧算法开发框架HiLens Framework;关键能力3:自动模型转换、模型压缩优化;关键能力4:开放的技能市场及预置丰富的Skill技能。二、Why众所周知,传统视频分析流程一般是先通过智能IPC获取到设备,然后将视频流传到云端,最后通过云端存储与分析。其实,这样传统的方案会有以下几个缺点:全景视频上云宽带成本高;端侧仅能运算有限的算法;算法与硬件存在强绑定的特点,AI技能的扩展性较弱;用户对隐私数据上云较为敏感。与传统的视频分析流程相比,华为云HiLens的解决方案则是通过端侧设备结合智能IPC实现本地AI技能,视频帧传到云API,通过技能市场实现AI技能本地部署。对比传统方案,华为云的解决方案通过AI分析本地运行,大大降低成本。并且,端云协同实现的技能还可以按需进行加载和更新。当然,也支持第三方开发技能,同时保护隐私。华为HiLens平台的优势包含了端云协同推理、Skill开发框架、开箱即用的开发环境、跨平台设计、预置丰富的AI技能、开发者社区。三、How为了更加公正客观的测试HiLens Kit设备的性能,博主先后基于该设备采用了不同的技能进行了多次试验,在整个的试验测试过程中,一句话概括来讲,该设备的鲁棒性比较好并且性价比非常高。 博主将会按照时间线的顺序分享一下测评感悟。从才开始拿到该设备,后续的注册、安装、连接、实景测试的整个流程进行详细讲解,以博主自己和朋友们的亲身体验,与大家分享一下这款能够几乎覆盖全场景应用的可扩展性AI设备。图1 华为HiLens设备HiLens Kit设备的轻巧使其部署更加灵活和方便。一开始,刚拿到该设备的时候,博主还是很惊讶的,虽然已经看过它的官方图片,但是HiLens Kit设备(如图1所示)比博主想象中还是要小得多,小巧玲珑的设计使得其应用变得更加灵活、广泛。外观造型有点像坦克,中间的摄像头可以调整拍摄角度,90度的范围。如图若是,设备两侧是散热孔,后端最右侧是开关按钮,向右依次是电源插口、两个USB接口、HDMI接口、RST键、耳机接口、SD卡插槽、网线接口。图2 网线和HDMI线 HiLens Kit设备的安装需要观看官网教程,但实际操作起来也并不复杂。通过参考官网教程,几分钟就可以搞定。因为寄给博主的时候,没有附带额外的网线,于是,博主从某宝上买了一根网线,再加上博主已有的一根HDMI线,如图2所示。当这些材料准备齐全后,博主就进行了安装。安装之前,博主先是从官网上看了一遍安装和配置教程,其实比较简单,但是为了保证顺利安装,博主还是建议多看几遍安装教程。整个安装过程共有四个步骤:第一步,先用网线把HiLens Kit连接到了博主的电脑上。第二步,通过电脑配置HiLens Kit设备,将其设置到与电脑所在的同一个网段。第三步,利用Web端登录到设备,进入管理页面,进而来连接本地的WiFi。第四步,通过ssh登录到设备,实现注册,如图3。特别要注意的是,当博主进行到第四步操作的时候,出现了一个bug,大概的意思是没有权限访问资源。最后通过华为的客服人员告知,才发现是博主自己以前使用华为云服务的时候欠费所导致。当然只要华为云账户不欠费,就可以正常使用。当博主充上钱之后,重新登录,通过刷新设备列表,页面增加了新注册的设备!图3 设备注册 于是,博主就迫不及待的去点击了技能市场按钮,依次进行测试了人形检测、人脸属性识别、人脸特效、静态手势识别、疲劳驾驶检测等技能,如列表1所示。其中人脸特效和静态手势识别技能更加有趣味性和交互性。表1 市场技能为了让大家对Hilens Kit设备性能有一个直观的感受,博主将会从以下四个主要场景的几个主要应用分别进行测试,分享一下使用华为Hilens Kit的过程和感受。1、智慧家庭—“AI”与呵护家庭+AI的应用,在未来将会越来越多,这种无微不至的智能关怀,会给家人带来更多的温馨。华为Hilens设备包含了人脸识别和陌生人检测、婴儿哭声检测、人体姿态检测技能,利用AI技术不仅及时有效的展示了对家的“爱”,更重要的是呵护了带有温度的家。下图是对人脸属性识别和静态手势检测技能进行测试的效果。图4 手势识别测试2、智能园区—“AI”与守护智能园区的场景中,Hilens设备集成了车牌识别、人形车辆检测、安全帽检测的技能,不仅提高了车辆通行效率,更重要的是守护了人身安全。其中,还包括了趣味性的交互技能,比如人脸特效检测,呈现带有酷炫眼镜和大金链子的视觉效果。下图是对人脸特效技能进行测试的效果。 图5 人脸特效测试3、智能车载—“AI”与保护在智能驾驶领域,Hilens设备加入了人脸属性检测与识别、人脸对比、疲劳驾驶检测的技能。其中,人脸识别属性检测目前可检测到的属性分别是Age、Gender、Smile、Glasses、beard。下图是对人脸属性技能进行测试的效果。 图6 人脸属性识别测试4、智能商超—“AI”与监护随着无人超市的兴起,现代化的智能商业超市的布局也越来越多。Hilens设备中的VIP识别、人形轨迹检测、客流量统计等技能为商户实现无人超市提供了最为便捷的服务。四、Conclusion总体来讲,Hilens Kit设备的实时性非常好,响应非常快,测试的几个技能几乎没有误检,小目标检测也比较鲁棒,准确率高,能够实现精准检测和识别。经过多次测试,除了性别属性有时候会误检之外,其余的几个场景测试效果非常好。 在进行人脸属性实时检测时,即使博主实时的靠近和远离,Hilens Kit设备也几乎不会漏检,并且小目标检测效果也非常稳定,戴上眼镜与摘下眼镜也能实时区分,但是人脸的性别属性有时候会随着光线的变化存在误分类。在进行人脸特效测试时,自动带上戴上墨镜和大金链子的特效非常酷炫,增加了交互的趣味性,测试的时候没有漏检。在进行单目标静态手势识别的时候,不同手势的快速切换,实时检测也非常灵敏,测试的时候没有误检。Hilens Kit设备的可扩展性非常好。它能够辅助我们开发人员研发最新的AI技能,并将该技能快速下发到端侧设备,使得我们开发人员快速实现自己的idea。通过基于Hilens Kit设备的反复测试和改进,这种反馈性更能激励我们开发出更多更好的新技能,满足我们开发人员的成就感。使得我们技术人员不再单单是懂技术,而是更加直观感受了场景的业务需求,这种基于业务的理解会赋予我们开发人员拥有更多的优化技巧。当然,除了以上的优点,还有几点待改进的地方。首先,人脸的性别属性可以通过改进算法加强训练变得更加鲁棒。其次,在进行实时检测的时候,有时候会出现从散热器内产生的噪声,这一点也从侧面说明了AI设备的确需要较多的算力支持。众所周知,深度学习算法在进行实时推理的时候,大量的计算产生大量的热,所以需要及时散热。但是,如果考虑到价格因素,从性价比的角度,综合来说,Hilens Kit设备非常划算,值得购买。最后,感谢华为提供华为Hilens Kit的产品体验,以上是博主为广大粉丝朋友带来的分享。
  • [其他] 浅谈多模态模型
    CLIPCLIP是OpenAI提出的连接图像和文本特征表示的对比学习方法。论文: https://arxiv.org/abs/2103.00020ViLBERTViLBERT修改BERT中query条件下的key-value注意力机制,将其发展成一个多模态共注意transformer模块。LXMERTcross-attention在cross操作后加入一个全连接层,同时融合了图片和文字的信息。增加了一些预训练任务目标,比如Masked Cross-Modality LM。增加图像问答任务到预训练任务中(引入vqa等数据集的训练集)。论文:https://arxiv.org/abs/1908.07490VL-BERT模型在BERT的基础上在输入中嵌入一种新的视觉特征来适应视觉的相关内容。与BERT类似,模型主要由多层双向Transformer编码器组成。但与BERT只处理句子单词不同,VL-BERT把视觉元素和语言元素都作为输入,模型分别在图像的感兴趣区域(RoIs)和输入句子中的单词上定义相应特征。UNITER创新点:a) 有文本的预训练任务比没有文本的预训练任务效果更好b) Vison+Language 组合的预训练效果要好于单独的 Vision/Languagec) 最好的预训练组合是:MLM+ITM+MRC-kl+MRFPd) 将上面提到的四个数据一起训练效果最好,这也证明数据越多效果越好e) 扩大的数据集任务:a) MLM(conditioned on image,遮字模型)b) MRM(Mask Region Model,预测图像,回归或分类,有三种变体)--MRC(Mask Region Cls),MRFR(Mask Regin Feature Regress),MRC-KL(MRC + KL divergency)c) ITM(Image Text Match,图文是否一致)d) WRA(Word Region Alignment,字和图像的对齐任务)论文:https://arxiv.org/pdf/1908.08530.pdfImageBERT主要在与数据量,作者从网络上收集了一个大型的弱监督图像-文本数据集LAIT,包含了 10M(1千万)的 Text-Image pairs,这也是目前最大的一个数据集。论文:https://arxiv.org/abs/2001.07966Pixel-BERT论文:https://arxiv.org/abs/2004.00849a) 句子编码:采用跟bert一样的编码方式。b) 图片编码:对图片进行卷积,池化,最后得到一个特征矩阵(元素为特征向量),对其进行采样后,每个元素与一个semantic embedding相加,相当于一种偏置。最后展平,得到最终的像素特征编码。c) 多模态编码:将两种表示拼接在一起,过TRM,得到最终的表示。d) 任务:MLM任务和图片-文本匹配任务。Oscar: Object-Semantics Aligned Pre-training for Vision-Language Tasks ECCV 2020 motivation:提出了一种新的学习方法Oscar,它用图像中检测到的对象标签作为锚点,在一个共享的语义空间中对齐图像和语言模态。在一个有650万个图像-文本对的公共语料库上对Oscar模型进行了预训练,验证了Oscar的有效性。method&task:将词符、对象标签、区域特征作为输入,增加mask token loss和contrastive loss。论文:https://arxiv.org/abs/2004.06165InterBERT提出跨度更大的mask和高阶交互特征后保持模态独立性方法。 论文:https://arxiv.org/abs/2003.13198ViLT文本特征输入部分,将文本看成一个词序列,通过word embedding matrix转化成word embedding,然后和position embedding进行相加,最后和modal-type embedding进行concate。图像特征输入部分,将图像切块看成一个图像块序列,通过linear projection转化成visual embedding,然后和postion embedding进行相加,最后和modal-type embedding进行concate。其中word embedding和visual embedding通过可学习的modal-type embedding标志位来区分,其中0标志位表示word embedding部分,1标志位表示visual embedding部分。word embedding和visual embedding分别都嵌入了一个额外的可学习[class] embedding,方便和下游任务对接。类似clip单流
  • [技术干货] 体验华为云对话机器人服务 CBS及问题解决
    前言本篇文章体验华为云问答机器人API调用总结的文章,包含遇到的问题,如认鉴权等。一、开通使用来到华为云“免费体验中心”——>找到“对话机器人服务”——>开通免费体验​​在控制台找到对话机器人服务,可以看到机器人ID等信息。​新建语料在问答机器人列表中,单击“机器人管理”。在“问答机器人”页面左侧导航栏中选择“知识库 > 问答管理”,在问答管理页面执行如下操作。​在问答管理中单击​按钮新建问题分类,例如“IT问题”。在问答管理中单击“新建”创建问答语料​对话体验在页面右上角单击“对话体验”,展开对话窗口。在窗口中,输入“蓝屏了怎么办”,查看是否可以获得准确答案。您可以根据业务实际情况进行提问,当机器人无法回答时,建议根据实际情况补充语料或补充扩展问。​下面我们在现在的对话机器人基础上实现问答接口调用二、API调用这里选择java API调用和PostMan调用endpoint是你的开通服务的终端节点:cbs-ext.cn-north-4.myhuaweicloud.com​project_id:项目id​qabot_id:机器人id​POST:POST https://{endpoint}/v1/{project_id}/qabots/{qabot_id}/chat Request Header: Content-Type: application/json X-Auth-Token: 认证鉴权的信息 Request Body: { "question": "桌面云打不开了" } ​​Java语言:import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; public class CBSDemo { public void cbsDemo() { try { //endpoint、projectId、qabot_id需要替换成实际信息。 URL url = new URL("https://{endpoint}/v1/{project_id}/qabots/{qabot_id}/chat"); String token = "用户获取得到的实际token值"; HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoInput(true); connection.setDoOutput(true); connection.addRequestProperty("Content-Type", "application/json"); connection.addRequestProperty("X-Auth-Token", token); //输入参数 String body = "{\"question\": \"用户问\"}"; OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); osw.append(body); osw.flush(); InputStream is = connection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); while (br.ready()) { System.out.println(br.readLine()); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { CBSDemo CBSDemo = new CBSDemo(); CBSDemo.cbsDemo(); } } 现在Token的值大家还不知道,继续往下看。三、认证鉴权问题这里遇到的问题就是认证鉴权问题,说一下:华为云的这个token获取,出现错误返回的概率很大,解决和原因下面我会讲解。这里介绍Token认证:通过Token认证通用请求POST: https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "name": "***", "password": "***", "domain": { "name": "***" } } } }, "scope": { "project": { "name": "cn-north-4" } } } }上面的***都是需要替换的,替换成你的。Token获取控制台找到“我的凭证”:​​将上面图片的账号名填在下面:POST: https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "name": "***", "password": "自己的密码,如果自己以前没印象用过这个,很大概率是你的华为云账号的密码", "domain": { "name": "账号名" } } } }, "scope": { "project": { "name": "cn-north-4" } } } } 这里还有个name的值没有填,但也是很多开发者出现错误返回的原因:当你的统一认证的用户组只有admin时是不行的,这个具体原因我不太清楚,主要是华为云控制台自带的初始admin用户组是不行的,你需要自己创建一个新的用户组,创建一个新的用户添加到新创建的用户组就可,大致流程如下:​​​这时,上面的name就是haoze了,具体是你创建的用户名。然后用PostMan工具发送请求得到返回的token:​没有PostMan的可以使用华为云控制台的API Explorer工具​​总结以上就是华为对话机器人服务的体验讲解以及问题解决。
  • [交流吐槽] 4千元高端热水袋不能装沸水?物联网技术革新智能热水袋取暖体验
    近日,Burberry品牌的一款售价高达4400元的热水袋因不建议灌注沸水而引发热议。不少网友感到惊讶与困惑,4千多块真是买了个寂寞,毕竟这个价格能买到取暖器了!但从另一个角度来看,这恰好揭示了当前及未来智能家居领域对热水袋产品安全性和智能化提升的迫切需求。4400元的高端热水袋不能装沸水反映了未来产品设计的深思——图的是牌子,还是里子?未来,我们应该利用物联网技术革新,来优化热水袋的设计,提升用户体验,使其真正成为名副其实的高端产品。首先,物联网的核心在于设备间的智能连接和数据交换。未来的热水袋可以通过盈电物联网内置传感器实时监测水温,并通过无线模块将数据发送至用户的智能手机或家庭控制中心。用户不仅能通过手机应用随时查看热水袋的水温,还能根据个人偏好设置理想的温度范围,一旦水温过低或过高,应用会立即提醒用户进行调整。​此外,借助物联网的数据分析能力,智能热水袋可以学习用户的使用习惯,预测最佳加热时间和保温模式,从而减少能源浪费,并延长产品寿命。例如,如果用户通常在晚上睡前使用热水袋,那么设备可以自动提前加热到适宜温度,并在用户入睡后进入节能保温状态。安全性是设计任何产品时的首要考虑因素。智能热水袋应具备多重安全保护机制,如防干烧功能、过热自动断电等。通过盈电物联网技术,这些安全特性可以更加智能化。例如,热水袋能够检测内部水压,防止因过度注水而导致的潜在危险。同时,如果检测到外壳破损或密封不良,系统会自动通知用户进行维修或更换,确保使用安全。在用户体验方面,物联网技术可以使热水袋变得更加人性化。除了基础的温度调节,智能热水袋还可以提供按摩、冷热交替等多种模式,以适应不同的放松需求。甚至可以根据用户的身体状况,如月经不适或肌肉酸痛,推荐特定的热敷方案。物联网技术为热水袋带来了前所未有的智能化机遇。从实时温控到个性化服务,再到安全保障,智能热水袋的设计正朝着更加精准、便捷和安全的方向发展。未来,随着盈电物联网技术的不断进步和用户需求的日益多样化,智能热水袋将成为家居生活中不可或缺的一部分,带给人们更多的温暖与关怀。
  • [技术干货] 利用GAN生成指定棱角性的集料
    利用GAN生成指定棱角性的集料图像棱角性GA计算公式为:我们将GA作为条件变量输入生成器中,然后利用判别器从生成的图像中重建GA。利用条件变量GA来约束生成的图像,修改L2范数损失重建生成图像的标签,使得GA的值与生成图像的棱角性高度相关,相关的损失函数为:cond_loss = tf.square(tf.reduce_mean(label_out) - tf.reduce_mean(label_in))模型的训练结果:实验表明该生成器能够在一定程度上生成指定棱角性的图像,Notebook:
  • [技术干货] 云养猪 - 猪只关键点检测
    云养猪 - 猪只关键点检测关键点检测可用于猪只骨架提取、姿态识别、体重估计等多方面的研究,本文将基于ModelArts和ModelBox开发一个猪只关键点检测的AI应用,并将其部署到RK3568开发板上。视频链接:cid:link_4模型训练首先我们使用YOLOX训练了一个猪只目标检测模型,YOLOX是YOLO的无锚版本,设计更简单,且性能更好!它旨在弥合研究界和工业界之间的差距,详细内容可以参考Arxiv。我们使用猪只目标检测数据集进行训练,训练前对该数据集进行了图像增强,包含两类图像piglet、swine,拥有3065张jpg图像数据以及对应的xml标签文件,训练日志如下:之后利用TensorFlow开发一个猪只关键点检测模型,使用预训练网络MobileNetV2作为卷积基提取图像特征,模型训练与转换教程可以参考我们发布的Notebook:应用开发1、在VS Code中使用Remote-SSH远程连接RK3568开发板(算力:0.8Tops)2、下载ModelBox SDK插件安装运行3、查看技能模板,下载技能模板:single_hand_pose_yolox_mbv24、使用模板创建工程:single_pig_pose4.1、推理功能单元使用我们自己导出的模型进行替换并修改模型配置文件:4.2、修改条件功能单元的代码:4.3、修改通用功能单元代码和配置文件:4.4、修改模型配置文件并替换为我们自己开发的猪只关键点检测模型4.5、修改猪只关键点检测后处理功能单元和配置文件4.6、修改绘图功能单元代码5、查看流程图开启性能统计6、在bin/mock_task.toml配置输入输出,使用提前准备好的视频进行推理,选择推流到本地,执行bin/main.sh运行应用查看性能统计文件我们开发的应用平均每次推理(batch_size:4)耗时193 / 4 = 48ms,视频测试的帧率为1000 / 48 = 21fps,基本满足摄像头实时检测的要求。复现本案例所需资源(代码、模型、测试数据等)均可从single_pig_pose.zip获取。
  • [公告] 【获奖公示】1.5号直播 / DTSE Tech Talk丨NO.51:华为云DTT年度收官盛典:AI创造无限可能
    中奖结果公示感谢各位小伙伴参与本次活动,本次活动获奖名单如下所示。请获奖的伙伴在1月14日之前点击此处填写收货地址,如逾期未填写视为弃奖。再次感谢各位小伙伴参与本次活动,欢迎关注华为云DTSE Tech Talk 技术直播更多活动~【报名转发抽奖】奖项名单华为云账号昵称奖品hw090512683yd_235942659华为云定制Polo衫hid_a0211e-bd-x__swyd_230717006华为云定制Polo衫hid_y_w9dg_leuhuf8o小云悠悠zZ华为云定制Polo衫hw71474994yd_267218756华为云定制Polo衫hw053453872yd_224714878华为云定制Polo衫【我与DTT的独家记忆】奖项名单(奖品:华为云云宝公仔一套) 点击链接查看【专家坐堂有奖】奖项名单(奖品:华为云定制长袖卫衣) 点击链接查看【有奖调研】奖项名单账号奖品xiaozhongy华为云无线鼠标hw008562287华为云无线鼠标hid__cn8cjapw6ba12c华为云无线鼠标jackie306华为云无线鼠标linghz666华为云无线鼠标
  • [技术干货] 实验探索:利用GAN随机生成指定图像的优化思路
    我想使用GAN实现指定一个粒径和棱角性(比如我指定粒径是4.75,棱角性是1200),然后它可以随意生成想要集料形状和棱角性大小,如下图所示:我设计的GAN在训练过程中生成器图像分类Loss很容易出现欠拟合,该如何优化呢?我使用了3600张图像用作训练,判别器的分类效果一直很好,生成器训练几十轮后就会出现欠拟合。我目前怀疑模型在反向传播过程中使用多个loss会互相干扰,但是不知道从哪方面下手,末尾附注Notebook链接。
  • [问题求助] 人工智能服务的价格计费模式是怎样的?
    人工智能服务的价格计费模式是怎样的?
  • [问题求助] 如何使用人脸识别、语音识别、自然语言处理等人工智能服务?
    如何使用人脸识别、语音识别、自然语言处理等人工智能服务?
  • [问题求助] 华为云提供哪些人工智能相关的服务和产品?
    华为云提供哪些人工智能相关的服务和产品?
  • [问题求助] 你好,请问晟腾这边有什么支持的 LLM serving framework吗?
    在晟腾910 npu服务器上安装vllm提示需要CUDA,当前是否有其他的可替代框架?