【AI达人创造营第二期】一文读懂textCNN模型原理

之前我们提到 CNN 时,通常会认为是属于计算机视觉领域。但是在2014年,Yoon Kim 针对 CNN 的输入层做了一些变形,从而提出了文本分类模型 textCNN。由于 CNN 在计算机视觉中,常被用于提取图像的局部特征图,且起到了很好的效果,所以该作者将其引入到 NLP 中,应用于文本分类任务,试图使用 CNN 捕捉文本中单词之间的关系。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

【ai达人创造营第二期】一文读懂textcnn模型原理 - 创想鸟

一文读懂textCNN模型原理

一、简介

之前我们提到 CNN 时,通常会认为是属于计算机视觉领域。但是在2014年,Yoon Kim 针对 CNN 的输入层做了一些变形,从而提出了文本分类模型 textCNN。由于 CNN 在计算机视觉中,常被用于提取图像的局部特征图,且起到了很好的效果,所以该作者将其引入到 NLP 中,应用于文本分类任务,试图使用 CNN 捕捉文本中单词之间的关系。

二、与传统 CNN 的不同

【AI达人创造营第二期】一文读懂textCNN模型原理 - 创想鸟        

图一-textCNN架构

与传统图像的CNN网络相比, textCNN 在网络结构上没有任何变化,甚至更加简化了, 从图中可以看出textCNN 其实只有一层卷积,一层max-pooling, 最后将输出外接softmax 来n分类。

然而textCNN 最大的不同是在于输入数据的不同: 图像是二维甚至三维数据, 图像的卷积核是从左到右, 从上到下进行滑动来进行特征提取;自然语言是一维数据, 虽然经过word-embedding 生成了二维向量,但是对词向量做从左到右滑动来进行卷积没有意义。比如 “今天” 对应的向量[0, 0, 0, 0, 1], 按窗口大小为 1 * 2 从左到右滑动得到[0,0], [0,0], [0,0], [0, 1]这四个向量, 对应的都是”今天”这个词汇, 这种滑动没有帮助。

TextCNN最大优势在于网络结构简单 ,在模型网络结构如此简单的情况下,通过引入已经训练好的词向量依旧有很不错的效果,在多项数据数据集上超越benchmark。网络结构简单导致参数数目少, 计算量少, 训练速度快,在单机单卡的v100机器上,训练165万数据, 迭代26万步,半个小时左右可以收敛。

三、模型架构简析

《Convolutional Neural Networks for Sentence Classification》一文中最早给出了文本CNN的基本结构,而后《A Sensitivity Analysis …》一文专门做了各种控制变量的实验对比。

【AI达人创造营第二期】一文读懂textCNN模型原理 - 创想鸟        

图二-《Convolutional Neural Networks for Sentence Classification》模型示意图

【AI达人创造营第二期】一文读懂textCNN模型原理 - 创想鸟        

图三-《A Sensitivity Analysis …》[2]模型示意图

由于一条文本语句由 n 个词组成,而每个词又可以表示为一个 k 维的词向量,所以最初模型的输入可以看作是一个 n×k 的单通道图像。

之后经过卷积层处理。在卷积层中,选用了不同的卷积核来得到不同的特征图,且卷积核的宽度即词向量的维度 k,所以卷积在这里的作用是用于提取不同数量的单词构成的元组之间的关系,比如卷积核的大小为 3,那么则将相邻的三个词语当作是一个特征。

在上图一的第二个阶段可以看到,由于选用的卷积核宽度与词向量维度相同,所以最终得到的特征图也就表现为了 n 维向量,之后便是对得到的每一个特征图做一次max-pooling,并将max-pooling的结果作为全连接层的输入,并最终进行 Softmax 分类。

四、textCNN模型架构

我们仍以图一中文语句为例

(一)Word Embedding 分词构建词向量

如图一所示,textCNN 首先将 “今天天气很好,出来玩” 分词成”今天/天气/很好/,/出来/玩, 通过word2vec或者GLOV 等embedding 方式将每个词成映射成一个5维(维数可以自己指定)词向量, 如 “今天” -> [0,0,0,0,1], “天气” ->[0,0,0,1,0], “很好” ->[0,0,1,0,0]等等。【AI达人创造营第二期】一文读懂textCNN模型原理 - 创想鸟        

这样做的好处主要是将自然语言数值化,方便后续的处理。从这里也可以看出不同的映射方式对最后的结果是会产生巨大的影响, nlp 当中目前最火热的研究方向便是如何将自然语言映射成更好的词向量。我们构建完词向量后,将所有的词向量拼接起来构成一个6 * 5的二维矩阵,作为最初的输入。

(二)卷积池化层(convolution and pooling)

卷积(convolution)

文本卷积与图像卷积的不同之处在于只针对文本序列的一个方向(垂直)做卷积,卷积核的宽度固定为词向量的维度d。高度是超参数,可以设置。对句子单词每个可能的窗口做卷积操作得到特征图(feature map) c = [c_1, c_2, …, c_s-h+1]。

现在假设有一个卷积核,是一个宽度为d,高度为h的矩阵w,那么w有h∗d个参数需要被更新。对于一个句子,经过嵌入层之后可以得到矩阵AϵRs×d。 A[i:j]表示A的第i行到第j行, 那么卷积操作可以用如下公式表示:【AI达人创造营第二期】一文读懂textCNN模型原理 - 创想鸟        

叠加上偏置b,在使用激活函数f激活, 得到所需的特征。公式如下: 【AI达人创造营第二期】一文读懂textCNN模型原理 - 创想鸟        

具体卷积计算参考博客文本分类算法TextCNN原理详解(一)

对于多通道(channel)的说明

在CNN 中常常会提到一个词channel, 图三 中 深红矩阵与 浅红矩阵 便构成了两个channel 统称一个卷积核, 从这个图中也可以看出每个channel 不必严格一样, 每个4 * 5 矩阵与输入矩阵做一次卷积操作得到一个feature map. 在计算机视觉中,由于彩色图像存在 R, G, B 三种颜色, 每个颜色便代表一种channel。 【AI达人创造营第二期】一文读懂textCNN模型原理 - 创想鸟        

根据原论文作者的描述, 一开始引入channel 是希望防止过拟合(通过保证学习到的vectors 不要偏离输入太多)来在小数据集合获得比单channel更好的表现,后来发现其实直接使用正则化效果更好。

不过使用多channel 相比与单channel, 每个channel 可以使用不同的word embedding, 比如可以在no-static(梯度可以反向传播) 的channel 来fine tune 词向量,让词向量更加适用于当前的训练。

对于channel在textCNN 是否有用, 从论文的实验结果来看多channels并没有明显提升模型的分类能力, 七个数据集上的五个数据集 单channel 的textCNN 表现都要优于 多channels的textCNN。

最大池化(max-pooling)

【AI达人创造营第二期】一文读懂textCNN模型原理 - 创想鸟        

得到feamap = [1,1,2] 后, 从中选取一个最大值[2] 作为输出, 便是max-pooling。max-pooling 在保持主要特征的情况下, 大大降低了参数的数目, 从图五中可以看出 feature map 从 三维变成了一维, 好处有如下两点:

1、降低了过拟合的风险, feature map = [1, 1, 2] 或者[1, 0, 2] 最后的输出都是[2], 表明开始的输入即使有轻微变形, 也不影响最后的识别。

2、参数减少, 进一步加速计算。

pooling 本身无法带来平移不变性(图片有个字母A, 这个字母A 无论出现在图片的哪个位置, 在CNN的网络中都可以识别出来),卷积核的权值共享才能.

max-pooling的原理主要是从多个值中取一个最大值,做不到这一点。cnn 能够做到平移不变性,是因为在滑动卷积核的时候,使用的卷积核权值是保持固定的(权值共享), 假设这个卷积核被训练的就能识别字母A, 当这个卷积核在整张图片上滑动的时候,当然可以把整张图片的A都识别出来。

(三)优化与正则化

池化层后面加上全连接层和SoftMax层做分类任务,得到各个类别比如 label 为1 的概率以及label 为-1的概率。同时防止过拟合,一般会添加L2和Dropout正则化方法。最后整体使用梯度法进行参数的更新模型的优化。

五、案例与代码实现

本文案例参考飞桨项目THUCNews数据集使用TextCNN完成文本分类任务。案例采用 THUCNews 数据集,由清华大学自然语言处理实验室根据新浪新闻RSS订阅频道2005~2011年间的历史数据筛选过滤生成,包含74万篇新闻文档(2.19 GB),均为UTF-8纯文本格式。其在原始新浪新闻分类体系的基础上,重新整合划分出14个候选分类类别:财经、cai票、房产、股票、家居、教育、科技、社会、时尚、时政、体育、星座、游戏、娱乐。

(一)环境配置

In [1]

import pandas as pdimport numpy as npimport paddleimport paddle.nn as nnfrom paddle.io import DataLoader, Datasetimport paddle.optimizer as optimfrom paddlenlp.data import Padimport jiebafrom collections import Counter

   

(二)数据准备

In [2]

data = pd.read_csv("data/data45260/Train.txt", sep='t', names=['ClassNo', 'ClassName', 'Sentence'])print("Train Set")print(data.head())print(data.info())pred_data = pd.read_csv("data/data45260/Test.txt", sep='t', names=['Sentence'])print("Pred Set")print(pred_data.head())print(pred_data.info())

       

Train Set   ClassNo ClassName            Sentence0        0        财经        上证50ETF净申购突增1        0        财经        交银施罗德保本基金将发行2        0        财经  基金公司不裁员反扩军 走访名校揽人才3        0        财经  基金巨亏30亿 欲打开云天系跌停自救4        0        财经          基金市场周二缩量走低RangeIndex: 752476 entries, 0 to 752475Data columns (total 3 columns): #   Column     Non-Null Count   Dtype ---  ------     --------------   -----  0   ClassNo    752476 non-null  int64  1   ClassName  752476 non-null  object 2   Sentence   752475 non-null  objectdtypes: int64(1), object(2)memory usage: 17.2+ MBNonePred Set                  Sentence0  北京君太百货璀璨秋色 满100省353020元1        教育部:小学高年级将开始学习性知识2    专业级单反相机 佳能7D单机售价9280元3      星展银行起诉内地客户 银行强硬客户无奈4   脱离中国的实际 强压RMB大幅升值只能是梦想RangeIndex: 83599 entries, 0 to 83598Data columns (total 1 columns): #   Column    Non-Null Count  Dtype ---  ------    --------------  -----  0   Sentence  83599 non-null  objectdtypes: object(1)memory usage: 653.2+ KBNone

       In [3]

## 注意到训练集中语句与数据数目不匹配,需删除无效数据data.dropna(axis=0, how='any', inplace=True)X = data['Sentence'].valuesY = data['ClassNo'].valuesY_name = data['ClassName'][np.sort(np.unique(data['ClassName'], return_index=True)[1])].valuesY_dict = dict([val for val in zip(np.unique(Y), Y_name)])

   

数据预处理,中文语句的处理需要注意中文分词及停用词的去除。根据提供的中文停用词数据集,将其数据进行加载。然后使用 jieba 包提供的中文分词功能,将训练集的输入语句每一句首先进行分词,调用 jieba.lcut(s) 进行分词并且返回分词后的列表。对于列表中的每一个词语,查看是否在停用词表中出现,如果出现则将其删除。

In [4]

def preprocess(data):    stopwords = open("data/data81223/stopwords.txt").read().split('n')    new_data = []    for row in data:        row = jieba.lcut(row)  # 中文分词        new_row = []        for word in row:            if word not in stopwords:                new_row.append(word)        new_data.append(new_row)    return np.array(new_data)corpus = preprocess(X)print(corpus[42])

       

Building prefix dict from the default dictionary ...Dumping model to file cache /tmp/jieba.cacheLoading model cost 0.835 seconds.Prefix dict has been built successfully.

       

['跌停', '虽未', '打开', '交易', '已', '活跃', ' ', '基金', '市价', '估值', '云天化']

       In [5]

## 构建词表def build_vocab(data):    word2id = {}    vocab = Counter()    for row in data:        vocab.update(row)    vocab = sorted(vocab.items(), key=lambda x: x[1], reverse=True)    vocab = [('', 0)] + list(vocab) + [('', 0)]    word2id = {word[0]: i for i, word in enumerate(vocab)}    return word2iddef get_ids(data, word2id):    ids =  []    for row in data:        id_ = list(map(lambda x: word2id.get(x, word2id['']), row))        ids.append(id_)    return np.array(ids)def padding(data):    return Pad(pad_val=0)(data)word2id = build_vocab(corpus)ids = get_ids(corpus, word2id)padding_ids = padding(ids)print(padding_ids[42])print(padding_ids[56748])

       

[ 2181 80653  4283   170    37  1070     1    19 12830   879 29555     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0][ 1908  4439   319 25054   126  2642   329    13    20   213   231  6516     2     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0]

       In [6]

## 重写Datasetclass MyDataset(Dataset):    def __init__(self, X, Y):        super(MyDataset, self).__init__()        self.X = X        self.Y = Y    def __len__(self):        return self.X.shape[0]    def __getitem__(self, index):        return self.X[index], self.Y[index]

   In [7]

## 划分数据集————训练集、测试集、开发集def split(X, Y):    idx = [i for i in range(0, X.shape[0])]    np.random.shuffle(idx)    train_len = int(0.9 * len(idx))    return X[idx[:train_len]], Y[idx[:train_len]],            X[idx[train_len:]], Y[idx[train_len:]]train_X, train_Y, test_X, test_Y = split(padding_ids, Y)print("Train Set: ", train_X.shape, train_Y.shape)print("Test Set: ", test_X.shape, test_Y.shape)

       

Train Set:  (677227, 75) (677227,)Test Set:  (75248, 75) (75248,)

       

(三)模型搭建

In [8]

## 搭建模型class TextCNN(paddle.nn.Layer):    def __init__(self, vocab_size, embedding_size, classes, pretrained=None, kernel_num=100, kernel_size=[3, 4, 5], dropout=0.5):        super(TextCNN, self).__init__()        self.vocab_size = vocab_size        self.embedding_size = embedding_size        self.classes = classes        self.pretrained = pretrained        self.kernel_num = kernel_num        self.kernel_size = kernel_size        self.dropout = dropout        if self.pretrained != None:            self.embedding = nn.Embedding(num_embeddings=self.vocab_size, embedding_dim=self.embedding_size, padding_idx=0 ,_weight=pretrained)        else:            self.embedding = nn.Embedding(num_embeddings=self.vocab_size, embedding_dim=self.embedding_size, padding_idx=0)        self.convs = nn.LayerList([nn.Conv2D(1, self.kernel_num, (kernel_size_, embedding_size)) for kernel_size_ in self.kernel_size])        self.dropout = nn.Dropout(self.dropout)        self.linear = nn.Linear(3 * self.kernel_num, self.classes)    def forward(self, x):        embedding = self.embedding(x).unsqueeze(1)        convs = [nn.ReLU()(conv(embedding)).squeeze(3) for conv in self.convs]        pool_out = [nn.MaxPool1D(block.shape[2])(block).squeeze(2) for block in convs]        pool_out = paddle.concat(pool_out, 1)        logits = self.linear(pool_out)        return logits

   In [9]

## 训练配置BATCH_SIZE = 50EMBEDDING_SIZE = 150LEARNING_RATE = 0.00005EPOCHS = 5 # 5device = paddle.device.get_device()  #注意配置环境必须是GPU,否则以下训练程序将无法运行print(device)

       

gpu:0

       In [10]

## 模型训练与评估Train_Loader = DataLoader(MyDataset(paddle.to_tensor(train_X), paddle.to_tensor(train_Y)), batch_size=BATCH_SIZE, shuffle=True)Test_Loader = DataLoader(MyDataset(paddle.to_tensor(test_X), paddle.to_tensor(test_Y)), batch_size=BATCH_SIZE, shuffle=True)model = TextCNN(vocab_size=len(word2id), embedding_size=EMBEDDING_SIZE, classes=len(Y_dict))print(model)optimizer = optim.Adam(parameters=model.parameters(), learning_rate=LEARNING_RATE)criterion = nn.CrossEntropyLoss()for epoch in range(0, EPOCHS):    Train_Loss, Test_Loss = [], []    Train_Acc, Test_Acc = [], []    model.train()    for i, (x, y) in enumerate(Train_Loader):        x = x.cuda()        y = y.cuda()        pred = model(x)        loss = criterion(pred, y)        Train_Loss.append(loss.item())        Train_Acc.append(paddle.metric.accuracy(pred, y).numpy())        loss.backward()        optimizer.step()        optimizer.clear_grad()    model.eval()    for i, (x, y) in enumerate(Test_Loader):        x = x.cuda()        y = y.cuda()        pred = model(x)        Test_Loss.append(criterion(pred, y).item())        Test_Acc.append(paddle.metric.accuracy(pred, y).numpy())    print(        "Epoch: [{}/{}] TrainLoss/TestLoss: {:.4f}/{:.4f} TrainAcc/TestAcc: {:.4f}/{:.4f}".format(         epoch + 1, EPOCHS,         np.mean(Train_Loss), np.mean(Test_Loss),         np.mean(Train_Acc), np.mean(Test_Acc)         )     )

       

W0221 10:12:08.730477   101 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 10.1, Runtime API Version: 10.1W0221 10:12:08.736320   101 device_context.cc:465] device: 0, cuDNN Version: 7.6.

       

TextCNN(  (embedding): Embedding(249925, 150, padding_idx=0, sparse=False)  (convs): LayerList(    (0): Conv2D(1, 100, kernel_size=[3, 150], data_format=NCHW)    (1): Conv2D(1, 100, kernel_size=[4, 150], data_format=NCHW)    (2): Conv2D(1, 100, kernel_size=[5, 150], data_format=NCHW)  )  (dropout): Dropout(p=0.5, axis=None, mode=upscale_in_train)  (linear): Linear(in_features=300, out_features=14, dtype=float32))Epoch: [1/5] TrainLoss/TestLoss: 0.6914/0.3004 TrainAcc/TestAcc: 0.8045/0.9109Epoch: [2/5] TrainLoss/TestLoss: 0.2333/0.2359 TrainAcc/TestAcc: 0.9311/0.9292Epoch: [3/5] TrainLoss/TestLoss: 0.1707/0.2199 TrainAcc/TestAcc: 0.9486/0.9337Epoch: [4/5] TrainLoss/TestLoss: 0.1364/0.2162 TrainAcc/TestAcc: 0.9585/0.9347Epoch: [5/5] TrainLoss/TestLoss: 0.1125/0.2177 TrainAcc/TestAcc: 0.9657/0.9356

       In [11]

## 保存模型paddle.save(model.state_dict(), "TextCNN.pdparams")paddle.save(optimizer.state_dict(), "Adam.pdparams")

   

(四)预测数据与效果检测

In [12]

## 预测数据准备pred_X = pred_data['Sentence'].valuespred_corpus = preprocess(pred_X)pred_ids = get_ids(pred_corpus, word2id)pred_padding_ids = padding(pred_ids)print(pred_padding_ids.shape)## 预测过程,并将预测结果按照输入的训练集形式进行了保存Pred_Loader = DataLoader(MyDataset(paddle.to_tensor(pred_padding_ids), paddle.to_tensor(pred_padding_ids)), batch_size=BATCH_SIZE, shuffle=False)model.eval()pred_Y = []for i, (x, y) in enumerate(Pred_Loader):    x = x.cuda()    pred = model(x)    label = np.argmax(pred, axis=1)    pred_Y += list(label)## 可视化一些文本的预测结果pred_Name = [Y_dict[name] for name in pred_Y]MyPred = pd.DataFrame({'ClassNo': pred_Y, 'ClassName': pred_Name, 'Sentence': pred_X})print(MyPred.head())MyPred.to_csv('pred.csv', index=False)

       

(83599, 75)   ClassNo ClassName                 Sentence0        3        股票  北京君太百货璀璨秋色 满100省353020元1        5        教育        教育部:小学高年级将开始学习性知识2        6        科技    专业级单反相机 佳能7D单机售价9280元3        3        股票      星展银行起诉内地客户 银行强硬客户无奈4        3        股票   脱离中国的实际 强压RMB大幅升值只能是梦想

       

(五)封装功能 自定义文本输入

In [16]

model_params = paddle.load('TextCNN.pdparams')model_infer = TextCNN(vocab_size=len(word2id), embedding_size=EMBEDDING_SIZE, classes=len(Y_dict))model_infer.set_state_dict(model_params)sentence = input()infer_corpus = preprocess([sentence])infer_ids = get_ids(infer_corpus, word2id)infer_padding_ids = padding(infer_ids)model_infer.eval()val = model_infer(paddle.to_tensor(infer_padding_ids))label = np.argmax(val, axis=1)[0]print("Sentence: ", sentence, " label: ", Y_dict[label])

       

Sentence:  再次点球失手!如何评价梅西现在的踢球水平?  label:  体育

       

以上就是【AI达人创造营第二期】一文读懂textCNN模型原理的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/50386.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月8日 16:43:53
下一篇 2025年11月8日 16:47:41

相关推荐

  • 怎样用免费工具美化PPT_免费美化PPT的实用方法分享

    利用KIMI智能助手可免费将PPT美化为科技感风格,但需核对文字准确性;2. 天工AI擅长优化内容结构,提升逻辑性,适合高质量内容需求;3. SlidesAI支持语音输入与自动排版,操作便捷,利于紧急场景;4. Prezo提供多种模板,自动生成图文并茂幻灯片,适合学生与初创团队。 如果您有一份内容完…

    2025年12月6日 软件教程
    000
  • Pages怎么协作编辑同一文档 Pages多人实时协作的流程

    首先启用Pages共享功能,点击右上角共享按钮并选择“添加协作者”,设置为可编辑并生成链接;接着复制链接通过邮件或社交软件发送给成员,确保其使用Apple ID登录iCloud后即可加入编辑;也可直接在共享菜单中输入邮箱地址定向邀请,设定编辑权限后发送;最后在共享面板中管理协作者权限,查看实时在线状…

    2025年12月6日 软件教程
    100
  • REDMI K90系列正式发布,售价2599元起!

    10月23日,redmi k90系列正式亮相,推出redmi k90与redmi k90 pro max两款新机。其中,redmi k90搭载骁龙8至尊版处理器、7100mah大电池及100w有线快充等多项旗舰配置,起售价为2599元,官方称其为k系列迄今为止最完整的标准版本。 图源:REDMI红米…

    2025年12月6日 行业动态
    200
  • Linux中如何安装Nginx服务_Linux安装Nginx服务的完整指南

    首先更新系统软件包,然后通过对应包管理器安装Nginx,启动并启用服务,开放防火墙端口,最后验证欢迎页显示以确认安装成功。 在Linux系统中安装Nginx服务是搭建Web服务器的第一步。Nginx以高性能、低资源消耗和良好的并发处理能力著称,广泛用于静态内容服务、反向代理和负载均衡。以下是在主流L…

    2025年12月6日 运维
    000
  • Linux journalctl与systemctl status结合分析

    先看 systemctl status 确认服务状态,再用 journalctl 查看详细日志。例如 nginx 启动失败时,systemctl status 显示 Active: failed,journalctl -u nginx 发现端口 80 被占用,结合两者可快速定位问题根源。 在 Lin…

    2025年12月6日 运维
    100
  • 华为新机发布计划曝光:Pura 90系列或明年4月登场

    近日,有数码博主透露了华为2025年至2026年的新品规划,其中pura 90系列预计在2026年4月发布,有望成为华为新一代影像旗舰。根据路线图,华为将在2025年底至2026年陆续推出mate 80系列、折叠屏新机mate x7系列以及nova 15系列,而pura 90系列则将成为2026年上…

    2025年12月6日 行业动态
    100
  • TikTok视频无法下载怎么办 TikTok视频下载异常修复方法

    先检查链接格式、网络设置及工具版本。复制以https://www.tiktok.com/@或vm.tiktok.com开头的链接,删除?后参数,尝试短链接;确保网络畅通,可切换地区节点或关闭防火墙;更新工具至最新版,优先选用yt-dlp等持续维护的工具。 遇到TikTok视频下载不了的情况,别急着换…

    2025年12月6日 软件教程
    100
  • Linux如何优化系统性能_Linux系统性能优化的实用方法

    优化Linux性能需先监控资源使用,通过top、vmstat等命令分析负载,再调整内核参数如TCP优化与内存交换,结合关闭无用服务、选用合适文件系统与I/O调度器,持续按需调优以提升系统效率。 Linux系统性能优化的核心在于合理配置资源、监控系统状态并及时调整瓶颈环节。通过一系列实用手段,可以显著…

    2025年12月6日 运维
    000
  • 曝小米17 Air正在筹备 超薄机身+2亿像素+eSIM技术?

    近日,手机行业再度掀起超薄机型热潮,三星与苹果已相继推出s25 edge与iphone air等轻薄旗舰,引发市场高度关注。在此趋势下,多家国产厂商被曝正积极布局相关技术,加速抢占这一细分赛道。据业内人士消息,小米的超薄旗舰机型小米17 air已进入筹备阶段。 小米17 Pro 爆料显示,小米正在评…

    2025年12月6日 行业动态
    000
  • 「世纪传奇刀片新篇」飞利浦影音双11声宴开启

    百年声学基因碰撞前沿科技,一场有关声音美学与设计美学的影音狂欢已悄然引爆2025“双十一”! 当绝大多数影音数码品牌还在价格战中挣扎时,飞利浦影音已然开启了一场跨越百年的“声”活革命。作为拥有深厚技术底蕴的音频巨头,飞利浦影音及配件此次“双十一”精准聚焦“传承经典”与“设计美学”两大核心,为热爱生活…

    2025年12月6日 行业动态
    000
  • 荣耀手表5Pro 10月23日正式开启首销国补优惠价1359.2元起售

    荣耀手表5pro自9月25日开启全渠道预售以来,市场热度持续攀升,上市初期便迎来抢购热潮,一度出现全线售罄、供不应求的局面。10月23日,荣耀手表5pro正式迎来首销,提供蓝牙版与esim版两种选择。其中,蓝牙版本的攀登者(橙色)、开拓者(黑色)和远航者(灰色)首销期间享受国补优惠价,到手价为135…

    2025年12月6日 行业动态
    000
  • Vue.js应用中配置环境变量:灵活管理后端通信地址

    在%ignore_a_1%应用中,灵活配置后端api地址等参数是开发与部署的关键。本文将详细介绍两种主要的环境变量配置方法:推荐使用的`.env`文件,以及通过`cross-env`库在命令行中设置环境变量。通过这些方法,开发者可以轻松实现开发、测试、生产等不同环境下配置的动态切换,提高应用的可维护…

    2025年12月6日 web前端
    000
  • VSCode终端美化:功率线字体配置

    首先需安装Powerline字体如Nerd Fonts,再在VSCode设置中将terminal.integrated.fontFamily设为’FiraCode Nerd Font’等支持字体,最后配合oh-my-zsh的powerlevel10k等Shell主题启用完整美…

    2025年12月6日 开发工具
    000
  • 环境搭建docker环境下如何快速部署mysql集群

    使用Docker Compose部署MySQL主从集群,通过配置文件设置server-id和binlog,编写docker-compose.yml定义主从服务并组网,启动后创建复制用户并配置主从连接,最后验证数据同步是否正常。 在Docker环境下快速部署MySQL集群,关键在于合理使用Docker…

    2025年12月6日 数据库
    000
  • Xbox删忍龙美女角色 斯宾塞致敬板垣伴信被喷太虚伪

    近日,海外游戏推主@HaileyEira公开发表言论,批评Xbox负责人菲尔·斯宾塞不配向已故的《死或生》与《忍者龙剑传》系列之父板垣伴信致敬。她指出,Xbox并未真正尊重这位传奇制作人的创作遗产,反而在宣传相关作品时对内容进行了审查和删减。 所涉游戏为年初推出的《忍者龙剑传2:黑之章》,该作采用虚…

    2025年12月6日 游戏教程
    000
  • 如何在mysql中分析索引未命中问题

    答案是通过EXPLAIN分析执行计划,检查索引使用情况,优化WHERE条件写法,避免索引失效,结合慢查询日志定位问题SQL,并根据查询模式合理设计索引。 当 MySQL 查询性能下降,很可能是索引未命中导致的。要分析这类问题,核心是理解查询执行计划、检查索引设计是否合理,并结合实际数据访问模式进行优…

    2025年12月6日 数据库
    000
  • VSCode入门:基础配置与插件推荐

    刚用VSCode,别急着装一堆东西。先把基础设好,再按需求加插件,效率高还不卡。核心就三步:界面顺手、主题舒服、功能够用。 设置中文和常用界面 打开软件,左边活动栏有五个图标,点最下面那个“扩展”。搜索“Chinese”,装上官方出的“Chinese (Simplified) Language Pa…

    2025年12月6日 开发工具
    000
  • VSCode性能分析与瓶颈诊断技术

    首先通过资源监控定位异常进程,再利用开发者工具分析性能瓶颈,结合禁用扩展、优化语言服务器配置及项目设置,可有效解决VSCode卡顿问题。 VSCode作为主流的代码编辑器,虽然轻量高效,但在处理大型项目或配置复杂扩展时可能出现卡顿、响应延迟等问题。要解决这些性能问题,需要系统性地进行性能分析与瓶颈诊…

    2025年12月6日 开发工具
    000
  • php查询代码怎么写_php数据库查询语句编写技巧与实例

    在PHP中进行数据库查询,最常用的方式是使用MySQLi或PDO扩展连接MySQL数据库。下面介绍基本的查询代码写法、编写技巧以及实用示例,帮助你高效安全地操作数据库。 1. 使用MySQLi进行查询(面向对象方式) 这是较为推荐的方式,适合大多数中小型项目。 // 创建连接$host = ‘loc…

    2025年12月6日 后端开发
    000
  • php数据库如何实现数据缓存 php数据库减少查询压力的方案

    答案:PHP结合Redis等内存缓存系统可显著提升Web应用性能。通过将用户信息、热门数据等写入内存缓存并设置TTL,先查缓存未命中再查数据库,减少数据库压力;配合OPcache提升脚本执行效率,文件缓存适用于小型项目,数据库缓冲池优化和读写分离进一步提升性能,推荐Redis为主并防范缓存穿透与雪崩…

    2025年12月6日 后端开发
    000

发表回复

登录后才能评论
关注微信