【复现日志】Clustering-Based Speech Emotion Recognition by Incorporating Learned Features and Deep BiLSTM

本文主要是介绍【复现日志】Clustering-Based Speech Emotion Recognition by Incorporating Learned Features and Deep BiLSTM,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Clustering-Based Speech Emotion Recognition by Incorporating Learned Features and Deep BiLSTM

复现日志


2021/11/22

阅读文章后初步构思复现内容:

  1. 数据集的下载和管理(注意speaker dependent和speaker independent数据集处理方式是不同的,需要设置一个超参获取数据信息,并存储到numpy数组当中)
  • speaker dependent是将所有文件混合后,随机选取80%数据作为测试和20%数据作为验证和测试。
  • speaker dependent是按照speaker进行五折交叉验证,80%的人用来训练,20%的人用来验证和测试。
    初步考虑将所有文件按照speaker划分文件夹,但是经过观察之后发现对于IEMOCAP数据集来说,session中的男女数据是混杂在一起的,带有“M”和“F”字样,考虑后续获得原始数据后,在训练前转化为语谱图阶段再进行划分,划分后每个session文件夹包含两个speaker,命名为M和F,每个性别文件夹内是两个npy文件,命名为data和label,分别存放聚类后的片段和标签。
  1. 将数据分为片段,窗长为500ms,有25%交叠,每个句子分别处理,存储到numpy数组当中作为处理后的数据,数据的形状大致为(样本数,片段数目,每个片段的数据长度)。
  2. 将上面处理好的数据进行聚类,距离度量使用RBF而不是欧拉距离矩阵,首先确定K值,阈值threshold动态计算[32],具体操作方式看一下该文章,K值确定后,进行K-Means聚类,将每个语段中距离每类最近的一个片段作为key segment,将所有key segment按照speaker存储到npy文件当中备用(上述为特征提取部分,参数一旦改变需要重新运行上面的程序),聚类结果最好做一个可视化,只展示部分数据(考虑4*4窗格)【这里先不加,后面有需要的话,可以添加可视化功能】。
  3. 构建后面的训练模型,CNN与LSTM部分是在一起训练的,可以同时写在一个模型里,但是CNN部分是预训练的,而且是一部分网络,可以在训练之前初始化参数时把预训练参数赋值好,然后LSTM进行空的初始化。这里注意双向LSTM的写法,是两层LSTM,可参考网络资料。LSTM最后一个时间步长的输出加log softmax进行结果预测,这里不要忘记对阈值确定的系数 β \beta β进行寻优。
  4. 训练过程参数初步考虑:
  • epoch = 100
  • learning rate = 0.001
  • optimizer = Adam
  • loss = 对数交叉熵
  • equipment = RTX 3060 GPU
    五折交叉验证需要根据数据集不同进行调整,同样需要设置if选择超参数决定
  1. 最后的结果需要speaker dependent和speaker independent分别的准确率、召回率、F1分数共2 * 3 * 3 (18个)数据,有必要可以加上WA,还有二者对应的混淆矩阵3 * 2(6个),这里只用IEMOCAP的话,需要SD、SI的三个数据3*2共6个数据和两个混淆矩阵。

数据预处理 2021/11/24

首先采用IEMOCAP数据集作为搭建,后来的数据集还未下载,所以暂时先不考虑数据集接口的更换问题。
IEMOCAP数据集的结构如下所示:
在这里插入图片描述
共有5个session,其中共有10种情感,这里文中只用了4种:anger、hapiness、neutral和sadness,所以将其他没用的数据删掉,保留这四种情感即可。首先要进行的是分帧,即将所有的语音数据读取后分成窗长500ms,25%重叠的(0.25*500=125 overlapping)片段,供后续使用,片段不足500ms的部分进行补零。该数据集采样率为16000Hz,那么每个片段
这里考虑几个函数:

  • 音频读取函数:输入文件路径,输出音频读取的numpy数组,每个数是每个采样点的值;(经过查找可以直接使用scipy中的read函数读取到numpy数组当中)
  • 片段切割函数:输入为数据、采样率、窗长和overlap的百分比,输出每个数据的切割结果,放在一个数组当中;
  • 主函数:按文件夹读取音频,切割后将音频存入对应新的文件夹中,最后得到的numpy文件的文件夹组织要和上面一样。
import os  # 用于文件处理
import numpy as np
import math
from scipy.io.wavfile import readdef process(data, sp_r, win_len=500, overlap=0.25):"""分割语段函数,输入为数据、采样率、窗长和overlap的百分比,输出每个数据的切割结果,放在一个数组当中"""num = len(data)  # 语句所有样本点数win_num = int(sp_r * (win_len / 1000))  # 计算每个窗中的样本点数目gap = math.floor(win_num * (1 - overlap))  # 非重叠部分的长度,需要跳过start = 0  # 窗口起始点result = []  # 结果列表while start < num:if start + win_num >= num:  # 如果最后一个窗长超过了原长度seg = np.zeros([win_num])  # 新建窗长大小全零数据seg[:len(data[start:])] = data[start:]  # 将尾部放入数组else:seg = data[start: start + win_num]  # 取出窗口内样本点result.append(seg)start += gap  # 后移gap大小return np.array(result)if __name__ == '__main__':data_base = 'IEMOCAP'  # 设置数据库sample_rate = 16000  # 数据库对应采样率target_name = 'IEMOCAP-preprocess'  # 预处理好的npy文件存放位置for dir_path, dir_names, filenames in os.walk(data_base):  # walk是一个游走遍历器,用于遍历该路径下所有文件if not os.path.exists(target_name + dir_path[len(data_base):]):os.mkdir(target_name + dir_path[len(data_base):])  # 创建新的存放路径for name in filenames:  # 对于每一个文件(string类型)path = os.path.join(dir_path, name)  # 获得相对地址wave_data = read(path)[1]  # 读取音频到numpy数组当中processed = process(wave_data, sample_rate)  # 对当前语段进行切割处理并返回切割结果new_dir = target_name + path[len(data_base): - (len(name) + 1)]  # 新的保存路径if not os.path.exists(new_dir):os.mkdir(new_dir)  # 创建新的存放路径np.save(new_dir + '\\' + name[:-3] + 'npy', processed)

更改数据库只需要更改data_base、sample_rate和target_name三个参数即可。


聚类 2021/11/25

上面经过预处理后,每个语段被分为若干大小相同的片段,我们而后需要对每个语段进行聚类以找到key segements,并将结果的npy文件保存在另外结构同源数据相同的文件夹中。需要注意的是,聚类需要一个参数K,即每个语段聚类类数,这个参数是通过一个阈值动态确定的,在每个语段中是不同的。
其中文献[32]给出了文中所使用方法Shot boundary detection的具体细节,文章连接:镜头边界检测,文中并没有具体说明是怎么计算距离的,所以这里暂时采用欧式距离矩阵计算两个片段间的距离。直接使用scipy中自带的cdist函数计算即可。根据文献[32]中的描述,阈值的设置公式如下,首先计算出所有相邻片段间的距离,对这些距离求均值,前面乘以一个权重作为阈值:

在这里插入图片描述
上面的权重自定义,一般 β \beta β取为5-10之间最佳,我考虑将 β \beta β作为外部参数,训练时调整参数寻优。
计算欧几里得距离时,我发现距离数值非常大,所以在计算前可以将所有数值按行进行z-score归一化,当然这里的归一化方法不是固定的,对结果的影响未知。但是归一化之后发现出错了,因为计算欧几里得距离时有可能算出inf或者nah,所以这里我去掉归一化了。
然后就是进行K-Means聚类了,可以单独有一个函数进行聚类,直接采用sklearn包的聚类算法,这里需要自定义距离度量,改成文中的RBF函数计算,具体自定义方法详见:sk-learn自定义距离度量。
聚类函数: 输入样本和聚类数,输出距离聚类中心最近的k个样本和标签情况(用来进行可视化),当然这里K=1没有意义,函数自己会将其归为一类。自带聚类函数中包含很多信息,有K个聚类中心和聚类结果标签。
K的取值显然是很重要的,有的时候会有6个片段只分为1类的情况,那只能选取一个片段训练,显然丢失了很多信息,这个K值选择的过程如果能优化一下,或者片段长度小一点,会不会好一些?
这里用sk-learn出现了一个警告信息:KMeans is known to have a memory leak on Windows with MKL, when there are less chunks than available threads. You can avoid it by setting the environment variable OMP_NUM_THREADS=1. 不知道是为什么
聚类这里还是有问题的,下面这个公式看不懂,没法完成自定义距离那里,暂时先放在这,采用欧氏距离的聚类,还有这里为什么不是把数据通过核函数直接映射到高维空间里呢?而是用核函数作为距离度量?
pyclustering包中其实是有聚类结果可视化的,如果后期有需要会加入可视化功能。

from scipy.spatial.distance import euclidean  # 计算欧氏距离用
import os
import numpy as np
# from kmeans import clustering
from sklearn.cluster import KMeans# def normalization(x):
#     """归一化函数"""
#     x_mean, x_std = np.mean(x, axis=0), np.std(x, axis=0)
#     x = (x - x_mean) / x_std
#     return xdef clustering(x, k):"""聚类函数,输入样本和聚类数,输出距离聚类中心最近的k个样本"""clf = KMeans(k)  # 聚类器r = clf.fit(x)  # 进行聚类,其中包含很多信息clustered = []  # 找出的关键片段for c in r.cluster_centers_:item = x[0]  # 初始化距离聚类中心最近的那个片段min_dist = np.Inf  # 记录最小距离值for i in x:if euclidean(c, i) < min_dist:  # 如果距离该中心的距离更短,更新结果item = imin_dist = euclidean(c, i)clustered.append(item)return clustered, r.labels_if __name__ == '__main__':origin_name = 'IEMOCAP-preprocess'  # 上一步预处理好的npy文件存放文件夹target_name = 'IEMOCAP-clustered'  # 聚类好结果存放文件夹名称thresh_weight = 1.5for dir_path, dir_names, filenames in os.walk(origin_name):  # 遍历数据文件夹下所有文件if not os.path.exists(target_name + dir_path[len(origin_name):]):os.mkdir(target_name + dir_path[len(origin_name):])  # 创建新的存放路径for name in filenames:  # 对于每一个文件(string类型)K = 1  # 聚类类别参数path = os.path.join(dir_path, name)  # 获得相对地址data = np.load(path)  # 读取一条音频处理结果# data = normalization(data)  # 归一化数据dists = []  # 存放所有相邻片段距离for seg in range(data.shape[0] - 1):  # 对于每一个片段来说(不包括最后一个)dist = euclidean(data[seg], data[seg + 1])  # 计算相邻两个片段的欧氏距离dists.append(dist)  # 存入容器中T = thresh_weight * np.mean(dists)  # 计算阈值for dis in dists:  # 根据阈值确定K值if dis > T:K += 1result, labels = clustering(data, K)  # 进行聚类,返回K个样本和label信息(用于绘图)new_dir = target_name + path[len(origin_name): - (len(name) + 1)]  # 新的保存路径if not os.path.exists(new_dir):os.mkdir(new_dir)  # 创建新的存放路径np.save(new_dir + '\\' + name[:-3] + 'npy', result)

生成语谱图 2021/11/26

下一步需要将上面聚类后的结果转换为语谱图放入CNN-BiLSTM网络进行训练,这里单独写一个函数将特征提取结果保存在和源文件结构相同的文件夹当中,过程很简单,即读取对应文件夹及文件后进行处理保存。
这里很奇怪,一个语段分成segments之后,最后生成的语谱图形状是(片段数,时间,频率)一个三维图,直接输入到网络当中吗?显然片段数是不固定的,但是CNN的输入通道大小是确定的,这是怎么回事?只有一种可能,就是取数据的时候取得是(batch-size,片段数,时间,频率)这样大小,但是将前两维度合并,作为二维图输入网络

import os
import numpy as np
import scipy.signal as signal"""运行顺序3:获取关键片段的频谱图作为特征并存储到文件中,结构同源"""if __name__ == '__main__':origin_name = 'IEMOCAP-clustered'  # 传统艺能target_name = 'IEMOCAP-feature'  # 传统艺能for dir_path, dir_names, filenames in os.walk(origin_name):  # 遍历数据文件夹下所有文件if not os.path.exists(target_name + dir_path[len(origin_name):]):os.mkdir(target_name + dir_path[len(origin_name):])  # 创建新的存放路径for name in filenames:  # 对于每一个文件(string类型)path = os.path.join(dir_path, name)  # 获得相对地址data = np.load(path)  # 读取语段数据result = []  # 存放所有片段STFT变换结果for i in range(len(data)):_, _, z = signal.stft(data[i])  # STFTresult.append(z)result = np.array(result)new_dir = target_name + path[len(origin_name): - (len(name) + 1)]  # 新的保存路径if not os.path.exists(new_dir):os.mkdir(new_dir)  # 创建新的存放路径np.save(new_dir + '\\' + name[:-3] + 'npy', result)

重构特征 2021/11/26

上面提取好特征后,结构和原来的文件夹是一样的,不利于训练,我们需要的是每个speaker在一个文件夹中,因为训练时需要五折交叉验证。每个speaker文件夹包含两个文件夹:feature和label,训练时直接读取feature和label中的数据。
在这里插入图片描述

import numpy as np
import os"""运行顺序4:重构文件夹形态,按照每一个speaker特征和标签进行划分,由于数据库本身特性,可能只适用于IEMOCAP,请勿改变任何文件夹名称"""if __name__ == '__main__':dic = {'ang':0, 'hap':1, 'neu':2, 'sad':3}  # 每种情绪对应标签origin_path = 'IEMOCAP-feature'  # 特征所在文件夹target_path = 'IEMOCAP-result'  # 目标文件夹if not os.path.exists(target_path):os.mkdir(target_path)  # 创建新的文件存放speaker = 0  # speaker计数器for i in range(1, 6):  # 遍历sessioncur_path = os.path.join(origin_path, 'Session{}'.format(i))  # 当前session的内容features_M = []  # 存放男性特征labels_M = []  # 存放男性标签features_F = []  # 存放女性特征labels_F = []  # 存放女性标签for key in dic.keys():  # 取出每个文件夹c_path = os.path.join(cur_path, key)  # 当前情绪所在文件夹for dir_path, dir_names, filenames in os.walk(c_path):  # 遍历当前情绪下所有文件for name in filenames:data = np.load(os.path.join(dir_path, name))  # 读取该文件if name[-8] == 'F':  # 如果该文件是女性for d in data:features_F.append(d)  # 添加特征labels_F.append(dic[key])  # 添加标签else:for d in data:features_M.append(d)  # 添加特征labels_M.append(dic[key])  # 添加标签# 创建第一个说话人文件夹,第一个人是男的speaker += 1save_path = os.path.join(target_path, 'speaker{}'.format(speaker))if not os.path.exists(save_path):os.mkdir(save_path)np.save(os.path.join(save_path, 'features.npy'), np.array(features_M))np.save(os.path.join(save_path, 'labels.npy'), np.array(labels_M))# 创建第二个说话人文件夹,第二个人是女的speaker += 1save_path = os.path.join(target_path, 'speaker{}'.format(speaker))if not os.path.exists(save_path):os.mkdir(save_path)np.save(os.path.join(save_path, 'features.npy'), np.array(features_F))np.save(os.path.join(save_path, 'labels.npy'), np.array(labels_F))

网络搭建与训练数据生成 2021/11/29

在这里插入图片描述
由上面的结构图可以看出,实际上网络只有两个部分,预训练的Resnet101和双向LSTM,而且经过查找资料发现ResNet的结构没有改变,可以直接调用预训练模型,最后一层的输出需要改变一下,改成softmax分类,类别数是数据库的情绪种类数。这里没有新建类直接调用的pytorch自带的模型进行训练,因为这两个模型没有自定义的成分。
这里比较坑的一点是文章好像没有给lstm的隐层数,我采用256作为隐藏层大小。

import torch
import torch.nn as nn
from torch.autograd import Variableclass LSTM_Model(nn.Module):"""定义LSTM的模型部分,需要获取最后一步输出作为结果"""def __init__(self, input_size, output_size, hidden_size, use_cuda=True):super(LSTM_Model, self).__init__()self.input_size = input_size  # 输入特征大小self.output_size = output_size  # 输出大小self.hidden_size = hidden_size  # 隐藏层大小self.use_cuda = use_cuda  # 是否使用gpu训练self.bi_lstm = nn.LSTM(input_size, hidden_size, num_layers=1, batch_first=True, bidirectional=True)  # 双向LSTMself.out_layer = nn.Linear(hidden_size * 2, output_size)  # 输出层,大小为类别数self.softmax = nn.LogSoftmax()  # 输出概率def forward(self, input, hidden):x, hidden = self.bi_lstm(input, hidden)  # 输入到LSTM中x = self.out_layer(x[:, -1, :])  # 输出结果(取最后一步输出)x = self.softmax(x)  # 输出概率return x, hiddendef init_hidden(self, batch_size):"""初始化LSTM隐藏状态,每个batch调用一次"""h0 = Variable(torch.zeros(2 * 1, batch_size, self.hidden_size))c0 = Variable(torch.zeros(2 * 1, batch_size, self.hidden_size))if self.use_cuda:h0.cuda()c0.cuda()return h0, c0

训练采用五折交叉验证,由于不同数据库中speaker的数目是不同的,需要自动设置训练和验证、测试集的大小。这里需要能够训练模块,分别是speaker independent和speaker dependent。
主循环是5个turns,为五轮交叉验证,其中每轮需要划分出训练数据、验证数据和测试数据,五轮结束后以每轮测试结果平均值作为最终准确率、平均召回率和F1分数。
每轮中每5个epoch(总epoch暂时设置为100)做一次验证集上验证并保留验证集loss最低模型作为最优模型,训练结束后使用最优模型在测试集上测试并获得准确率,每轮需要输出的内容有:

  • 验证EPOCH、验证集上的LOSS、UA\WA\召回率\F1分数(必要时加上最优模型存储提示)
  • 最优模型对应的EPOCH(完成)
  • 测试集平均UA、WA、召回率、F1分数
  • 每折训练集loss曲线和测试集混淆矩阵(最好不要在训练过程中显示,直接存储在文件中)

这里为了方便,我将SI和SD的训练过程数据存储在文件里,格式为“IEMOCAP-SI-train//fold1”以此类推,共5个文件夹,每一个文件夹里是训练、验证和测试数据,生成代码如下:

import torch
import numpy as np
import osif __name__ == '__main__':"""运行顺序5:Speaker Independent 训练数据生成,将五折测试、训练数据存储在文件中,节省训练时间"""root_path = 'IEMOCAP-result'  # 特征所在文件夹target_path = 'IEMOCAP-SI-train'  # 目标存放文件夹if not os.path.exists(target_path):os.mkdir(target_path)  # 创建新的存放路径for t in range(5):  # 进行5轮交叉训练验证start = t * 2  # 选择游标test_ind = start  # 测试人下标valid_ind = start + 1  # 验证人下标# 测试数据test_x = np.load(os.path.join(root_path, 'speaker{}'.format(test_ind + 1), 'features.npy'))test_x = np.expand_dims(test_x, 1)  # 拓展维度,作为一维图像test_y = np.load(os.path.join(root_path, 'speaker{}'.format(test_ind + 1), 'labels.npy'))# 验证数据valid_x = np.load(os.path.join(root_path, 'speaker{}'.format(valid_ind + 1), 'features.npy'))valid_x = np.expand_dims(valid_x, 1)  # 拓展维度,作为一维图像valid_y = np.load(os.path.join(root_path, 'speaker{}'.format(valid_ind + 1), 'labels.npy'))# 训练数据train_x = []train_y = []for person in range(10):if person != test_ind or person != valid_ind:train_x.extend([i for i in np.load(os.path.join(root_path, 'speaker{}'.format(person + 1),'features.npy'))])train_y.extend([i for i in np.load(os.path.join(root_path, 'speaker{}'.format(person + 1),'labels.npy'))])train_x = np.expand_dims(train_x, 1)  # 拓展维度,作为一维图像# 存储数据new_path = os.path.join(target_path, 'fold{}'.format(t))  # 存储路径if not os.path.exists(new_path):os.mkdir(new_path)  # 创建新的存放路径np.save(os.path.join(new_path, 'train_x.npy'), np.array(train_x))np.save(os.path.join(new_path, 'train_y.npy'), np.array(train_y))np.save(os.path.join(new_path, 'test_x.npy'), test_x)np.save(os.path.join(new_path, 'test_y.npy'), test_y)np.save(os.path.join(new_path, 'valid_x.npy'), valid_x)np.save(os.path.join(new_path, 'valid_y.npy'), valid_y)

在这里插入图片描述
接下来就是训练过程了,训练时数据可以直接从上面的文件夹中调用,节省了加载数据的时间。


训练与结果展示 2021/11/30

这里会遇到一个问题,就是预训练模型的输入是[64, 3, 7, 7]的,而我们的数据是[batch-size, 1, 257, 63]的,需要修改预训练模型第一层卷积的结构使得能够塞入数据得到正确的结果。
在检查过程中我遇到了一个严重的问题,loss不下降,经过检查数据和loss定义的部分都是正确的,那么问题可能出在模型上,我对文章的理解可能出现了错误,LSTM的输入在程序里是[batch, 1000, 1],也就是时间步长是1,每个时间步的特征长度是1,学不到东西。为了验证是不是模型出了问题,在训练步中我把第2和3维度进行交换,发现loss可以下降了,可以确定是lstm输入的部分出现了问题,但是时间步长为1的LSTM基本相当于全连接层,所以合理猜测,下面图应该是这个意思:
在这里插入图片描述
每个语音对应几个聚类后的segment,这些segement转换为spectrogram,那么训练数据的形状应该为(batch, seg_num, 257, 63),但是这样每个语段的segment大小就不一样了,没法输入到CNN,因为CNN要求的通道大小要一致。要么就是,一个一个塞到CNN中,得到结果之后再合在一起放入LSTM……
【我卡住了】……

这篇关于【复现日志】Clustering-Based Speech Emotion Recognition by Incorporating Learned Features and Deep BiLSTM的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/266625

相关文章

Spring Boot整合log4j2日志配置的详细教程

《SpringBoot整合log4j2日志配置的详细教程》:本文主要介绍SpringBoot项目中整合Log4j2日志框架的步骤和配置,包括常用日志框架的比较、配置参数介绍、Log4j2配置详解... 目录前言一、常用日志框架二、配置参数介绍1. 日志级别2. 输出形式3. 日志格式3.1 PatternL

开启mysql的binlog日志步骤详解

《开启mysql的binlog日志步骤详解》:本文主要介绍MySQL5.7版本中二进制日志(bin_log)的配置和使用,文中通过图文及代码介绍的非常详细,需要的朋友可以参考下... 目录1.查看是否开启bin_log2.数据库会把日志放进logs目录中3.查看log日志总结 mysql版本5.71.查看

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

SpringBoot如何使用TraceId日志链路追踪

《SpringBoot如何使用TraceId日志链路追踪》文章介绍了如何使用TraceId进行日志链路追踪,通过在日志中添加TraceId关键字,可以将同一次业务调用链上的日志串起来,本文通过实例代码... 目录项目场景:实现步骤1、pom.XML 依赖2、整合logback,打印日志,logback-sp

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

Spark MLlib模型训练—聚类算法 PIC(Power Iteration Clustering)

Spark MLlib模型训练—聚类算法 PIC(Power Iteration Clustering) Power Iteration Clustering (PIC) 是一种基于图的聚类算法,用于在大规模数据集上进行高效的社区检测。PIC 算法的核心思想是通过迭代图的幂运算来发现数据中的潜在簇。该算法适用于处理大规模图数据,特别是在社交网络分析、推荐系统和生物信息学等领域具有广泛应用。Spa

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录 在深度学习项目中,目标检测是一项重要的任务。本文将详细介绍如何使用Detectron2进行目标检测模型的复现训练,涵盖训练数据准备、训练命令、训练日志分析、训练指标以及训练输出目录的各个文件及其作用。特别地,我们将演示在训练过程中出现中断后,如何使用 resume 功能继续训练,并将我们复现的模型与Model Zoo中的