政安晨:【Keras机器学习示例演绎】(四十一)—— 使用预先训练的词嵌入

目录

设置

简介

下载新闻组 20 数据

让我们来看看这些数据

清洗数据并将数据分成训练集和验证集

创建词汇索引

加载预训练的词嵌入

建立模型

训练模型

导出端到端模型


政安晨的个人主页政安晨

欢迎 👍点赞✍评论⭐收藏

收录专栏: TensorFlow与Keras机器学习实战

希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!

本文目标:使用预训练的 GloVe 词嵌入对 Newsgroup20 数据集进行文本分类。

设置

import os

# Only the TensorFlow backend supports string inputs.
os.environ["KERAS_BACKEND"] = "tensorflow"

import pathlib
import numpy as np
import tensorflow.data as tf_data
import keras
from keras import layers

简介


在本例中,我们将展示如何使用预训练的单词嵌入来训练文本分类模型。

我们将使用 Newsgroup20 数据集,该数据集包含 20,000 条属于 20 个不同主题类别的留言板信息。

对于预训练的词嵌入,我们将使用 GloVe 嵌入。

下载新闻组 20 数据

data_path = keras.utils.get_file(
    "news20.tar.gz",
    "http://www.cs.cmu.edu/afs/cs.cmu.edu/project/theo-20/www/data/news20.tar.gz",
    untar=True,
)

让我们来看看这些数据

data_dir = pathlib.Path(data_path).parent / "20_newsgroup"
dirnames = os.listdir(data_dir)
print("Number of directories:", len(dirnames))
print("Directory names:", dirnames)

fnames = os.listdir(data_dir / "comp.graphics")
print("Number of files in comp.graphics:", len(fnames))
print("Some example filenames:", fnames[:5])
Number of directories: 20
Directory names: ['comp.sys.ibm.pc.hardware', 'comp.os.ms-windows.misc', 'comp.windows.x', 'sci.space', 'sci.crypt', 'sci.med', 'alt.atheism', 'rec.autos', 'rec.sport.hockey', 'talk.politics.misc', 'talk.politics.mideast', 'rec.motorcycles', 'talk.politics.guns', 'misc.forsale', 'sci.electronics', 'talk.religion.misc', 'comp.graphics', 'soc.religion.christian', 'comp.sys.mac.hardware', 'rec.sport.baseball']
Number of files in comp.graphics: 1000
Some example filenames: ['39638', '38747', '38242', '39057', '39031']

下面举例说明一个文件的内容:

print(open(data_dir / "comp.graphics" / "38987").read())
Newsgroups: comp.graphics
Path: cantaloupe.srv.cs.cmu.edu!das-news.harvard.edu!noc.near.net!howland.reston.ans.net!agate!dog.ee.lbl.gov!network.ucsd.edu!usc!rpi!nason110.its.rpi.edu!mabusj
From: mabusj@nason110.its.rpi.edu (Jasen M. Mabus)
Subject: Looking for Brain in CAD
Message-ID: <c285m+p@rpi.edu>
Nntp-Posting-Host: nason110.its.rpi.edu
Reply-To: mabusj@rpi.edu
Organization: Rensselaer Polytechnic Institute, Troy, NY.
Date: Thu, 29 Apr 1993 23:27:20 GMT
Lines: 7
Jasen Mabus
RPI student
I am looking for a hman brain in any CAD (.dxf,.cad,.iges,.cgm,etc.) or picture (.gif,.jpg,.ras,etc.) format for an animation demonstration. If any has or knows of a location please reply by e-mail to mabusj@rpi.edu.
Thank you in advance,
Jasen Mabus  

正如你所看到的,有一些标题行明确(第一行就是类别名称)或隐含地(例如,通过 "组织 "存档)泄露了文件的类别。让我们去掉这些标题:

samples = []
labels = []
class_names = []
class_index = 0
for dirname in sorted(os.listdir(data_dir)):
    class_names.append(dirname)
    dirpath = data_dir / dirname
    fnames = os.listdir(dirpath)
    print("Processing %s, %d files found" % (dirname, len(fnames)))
    for fname in fnames:
        fpath = dirpath / fname
        f = open(fpath, encoding="latin-1")
        content = f.read()
        lines = content.split("\n")
        lines = lines[10:]
        content = "\n".join(lines)
        samples.append(content)
        labels.append(class_index)
    class_index += 1

print("Classes:", class_names)
print("Number of samples:", len(samples))
Processing alt.atheism, 1000 files found
Processing comp.graphics, 1000 files found
Processing comp.os.ms-windows.misc, 1000 files found
Processing comp.sys.ibm.pc.hardware, 1000 files found
Processing comp.sys.mac.hardware, 1000 files found
Processing comp.windows.x, 1000 files found
Processing misc.forsale, 1000 files found
Processing rec.autos, 1000 files found
Processing rec.motorcycles, 1000 files found
Processing rec.sport.baseball, 1000 files found
Processing rec.sport.hockey, 1000 files found
Processing sci.crypt, 1000 files found
Processing sci.electronics, 1000 files found
Processing sci.med, 1000 files found
Processing sci.space, 1000 files found
Processing soc.religion.christian, 997 files found
Processing talk.politics.guns, 1000 files found
Processing talk.politics.mideast, 1000 files found
Processing talk.politics.misc, 1000 files found
Processing talk.religion.misc, 1000 files found
Classes: ['alt.atheism', 'comp.graphics', 'comp.os.ms-windows.misc', 'comp.sys.ibm.pc.hardware', 'comp.sys.mac.hardware', 'comp.windows.x', 'misc.forsale', 'rec.autos', 'rec.motorcycles', 'rec.sport.baseball', 'rec.sport.hockey', 'sci.crypt', 'sci.electronics', 'sci.med', 'sci.space', 'soc.religion.christian', 'talk.politics.guns', 'talk.politics.mideast', 'talk.politics.misc', 'talk.religion.misc']
Number of samples: 19997

实际上,有一个类别的文件数量并没有达到预期,但差异很小,所以这个问题仍然是一个平衡分类问题。

清洗数据并将数据分成训练集和验证集

# Shuffle the data
seed = 1337
rng = np.random.RandomState(seed)
rng.shuffle(samples)
rng = np.random.RandomState(seed)
rng.shuffle(labels)

# Extract a training & validation split
validation_split = 0.2
num_validation_samples = int(validation_split * len(samples))
train_samples = samples[:-num_validation_samples]
val_samples = samples[-num_validation_samples:]
train_labels = labels[:-num_validation_samples]
val_labels = labels[-num_validation_samples:]

创建词汇索引

让我们使用 TextVectorization 对数据集中的词汇进行索引。稍后,我们将使用同一层实例对样本进行矢量化。

我们的图层将只考虑前 20,000 个单词,并截断或填充序列,使其实际长度为 200 个词组。

vectorizer = layers.TextVectorization(max_tokens=20000, output_sequence_length=200)
text_ds = tf_data.Dataset.from_tensor_slices(train_samples).batch(128)
vectorizer.adapt(text_ds)

你可以通过 vectorizer.get_vocabulary() 来获取计算出的词汇量。让我们打印前 5 个词:

vectorizer.get_vocabulary()[:5]
['', '[UNK]', 'the', 'to', 'of']

让我们来矢量化一个测试句子:

output = vectorizer([["the cat sat on the mat"]])
output.numpy()[0, :6]
array([   2, 3480, 1818,   15,    2, 5830])

如您所见,"the "被表示为 "2"。既然 "the "是词汇表中的第一个词,为什么不是 0 呢?这是因为索引 0 是为填充保留的,而索引 1 则是为 "词汇表外 "标记保留的。

下面是一个将单词映射到其索引的 dict:

voc = vectorizer.get_vocabulary()
word_index = dict(zip(voc, range(len(voc))))

正如您所看到的,我们为测试句子获得了与上述相同的编码:

test = ["the", "cat", "sat", "on", "the", "mat"]
[word_index[w] for w in test]
[2, 3480, 1818, 15, 2, 5830]

加载预训练的词嵌入

让我们下载预训练的 GloVe 嵌入(压缩文件 822M)。
您需要运行以下命令:

!wget https://downloads.cs.stanford.edu/nlp/data/glove.6B.zip
!unzip -q glove.6B.zip
--2023-11-19 22:45:27--  https://downloads.cs.stanford.edu/nlp/data/glove.6B.zip
Resolving downloads.cs.stanford.edu (downloads.cs.stanford.edu)... 171.64.64.22
Connecting to downloads.cs.stanford.edu (downloads.cs.stanford.edu)|171.64.64.22|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 862182613 (822M) [application/zip]
Saving to: ‘glove.6B.zip’
glove.6B.zip        100%[===================>] 822.24M  5.05MB/s    in 2m 39s  
2023-11-19 22:48:06 (5.19 MB/s) - ‘glove.6B.zip’ saved [862182613/862182613]

该档案包含不同大小的文本编码向量:50 维、100 维、200 维、300 维。我们将使用 100 维的向量。

让我们创建一个将单词(字符串)映射到其 NumPy 向量表示的 dict:

path_to_glove_file = "glove.6B.100d.txt"

embeddings_index = {}
with open(path_to_glove_file) as f:
    for line in f:
        word, coefs = line.split(maxsplit=1)
        coefs = np.fromstring(coefs, "f", sep=" ")
        embeddings_index[word] = coefs

print("Found %s word vectors." % len(embeddings_index))
Found 400000 word vectors.

现在,让我们准备一个相应的嵌入矩阵,以便在 Keras 嵌入层中使用。这是一个简单的 NumPy 矩阵,其中索引 i 处的条目是我们的向量机词汇表中索引 i 的单词的预训练向量。

num_tokens = len(voc) + 2
embedding_dim = 100
hits = 0
misses = 0

# Prepare embedding matrix
embedding_matrix = np.zeros((num_tokens, embedding_dim))
for word, i in word_index.items():
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
        # Words not found in embedding index will be all-zeros.
        # This includes the representation for "padding" and "OOV"
        embedding_matrix[i] = embedding_vector
        hits += 1
    else:
        misses += 1
print("Converted %d words (%d misses)" % (hits, misses))
Converted 18021 words (1979 misses)

接下来,我们将预先训练好的单词嵌入矩阵载入嵌入层。
请注意,我们设置 trainable=False 是为了保持嵌入式的固定性(我们不想在训练过程中更新它们)。

from keras.layers import Embedding

embedding_layer = Embedding(
    num_tokens,
    embedding_dim,
    trainable=False,
)
embedding_layer.build((1,))
embedding_layer.set_weights([embedding_matrix])

建立模型


一个简单的 1D convnet,全局最大池化,最后是分类器。

int_sequences_input = keras.Input(shape=(None,), dtype="int32")
embedded_sequences = embedding_layer(int_sequences_input)
x = layers.Conv1D(128, 5, activation="relu")(embedded_sequences)
x = layers.MaxPooling1D(5)(x)
x = layers.Conv1D(128, 5, activation="relu")(x)
x = layers.MaxPooling1D(5)(x)
x = layers.Conv1D(128, 5, activation="relu")(x)
x = layers.GlobalMaxPooling1D()(x)
x = layers.Dense(128, activation="relu")(x)
x = layers.Dropout(0.5)(x)
preds = layers.Dense(len(class_names), activation="softmax")(x)
model = keras.Model(int_sequences_input, preds)
model.summary()
Model: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape              ┃    Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ input_layer (InputLayer)        │ (None, None)              │          0 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ embedding (Embedding)           │ (None, None, 100)         │  2,000,200 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ conv1d (Conv1D)                 │ (None, None, 128)         │     64,128 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ max_pooling1d (MaxPooling1D)    │ (None, None, 128)         │          0 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ conv1d_1 (Conv1D)               │ (None, None, 128)         │     82,048 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ max_pooling1d_1 (MaxPooling1D)  │ (None, None, 128)         │          0 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ conv1d_2 (Conv1D)               │ (None, None, 128)         │     82,048 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ global_max_pooling1d            │ (None, 128)               │          0 │
│ (GlobalMaxPooling1D)            │                           │            │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ dense (Dense)                   │ (None, 128)               │     16,512 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ dropout (Dropout)               │ (None, 128)               │          0 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ dense_1 (Dense)                 │ (None, 20)                │      2,580 │
└─────────────────────────────────┴───────────────────────────┴────────────┘
 Total params: 2,247,516 (8.57 MB)
 Trainable params: 2,247,516 (8.57 MB)
 Non-trainable params: 0 (0.00 B)

训练模型


首先,将字符串列表数据转换为整数索引的 NumPy 数组。数组采用右填充。

x_train = vectorizer(np.array([[s] for s in train_samples])).numpy()
x_val = vectorizer(np.array([[s] for s in val_samples])).numpy()

y_train = np.array(train_labels)
y_val = np.array(val_labels)

我们使用分类交叉熵作为损失,因为我们进行的是软最大分类。此外,由于我们的标签是整数,因此我们使用稀疏分类交叉熵(sparse_categorical_crossentropy)。

model.compile(
    loss="sparse_categorical_crossentropy", optimizer="rmsprop", metrics=["acc"]
)
model.fit(x_train, y_train, batch_size=128, epochs=20, validation_data=(x_val, y_val))
Epoch 1/20
   2/125 [37m━━━━━━━━━━━━━━━━━━━━  9s 78ms/step - acc: 0.0352 - loss: 3.2164 

WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1700434131.619687    6780 device_compiler.h:187] Compiled cluster using XLA!  This line is logged at most once for the lifetime of the process.

 125/125 ━━━━━━━━━━━━━━━━━━━━ 22s 123ms/step - acc: 0.0926 - loss: 2.8961 - val_acc: 0.2451 - val_loss: 2.1965
Epoch 2/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 10s 78ms/step - acc: 0.2628 - loss: 2.1377 - val_acc: 0.4421 - val_loss: 1.6594
Epoch 3/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 10s 78ms/step - acc: 0.4504 - loss: 1.5765 - val_acc: 0.5849 - val_loss: 1.2577
Epoch 4/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 10s 76ms/step - acc: 0.5711 - loss: 1.2639 - val_acc: 0.6277 - val_loss: 1.1153
Epoch 5/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 9s 74ms/step - acc: 0.6430 - loss: 1.0318 - val_acc: 0.6684 - val_loss: 0.9902
Epoch 6/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 9s 72ms/step - acc: 0.6990 - loss: 0.8844 - val_acc: 0.6619 - val_loss: 1.0109
Epoch 7/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 9s 70ms/step - acc: 0.7330 - loss: 0.7614 - val_acc: 0.6832 - val_loss: 0.9585
Epoch 8/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 8s 68ms/step - acc: 0.7795 - loss: 0.6328 - val_acc: 0.6847 - val_loss: 0.9917
Epoch 9/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 8s 64ms/step - acc: 0.8203 - loss: 0.5242 - val_acc: 0.7187 - val_loss: 0.9224
Epoch 10/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 8s 60ms/step - acc: 0.8506 - loss: 0.4265 - val_acc: 0.7342 - val_loss: 0.9098
Epoch 11/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 7s 56ms/step - acc: 0.8756 - loss: 0.3659 - val_acc: 0.7204 - val_loss: 1.0022
Epoch 12/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 7s 54ms/step - acc: 0.8921 - loss: 0.3079 - val_acc: 0.7209 - val_loss: 1.0477
Epoch 13/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 7s 54ms/step - acc: 0.9077 - loss: 0.2767 - val_acc: 0.7169 - val_loss: 1.0915
Epoch 14/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 6s 50ms/step - acc: 0.9244 - loss: 0.2253 - val_acc: 0.7382 - val_loss: 1.1397
Epoch 15/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 6s 49ms/step - acc: 0.9301 - loss: 0.2054 - val_acc: 0.7562 - val_loss: 1.0984
Epoch 16/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 5s 42ms/step - acc: 0.9373 - loss: 0.1769 - val_acc: 0.7387 - val_loss: 1.2294
Epoch 17/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 5s 41ms/step - acc: 0.9467 - loss: 0.1626 - val_acc: 0.7009 - val_loss: 1.4906
Epoch 18/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 5s 39ms/step - acc: 0.9471 - loss: 0.1544 - val_acc: 0.7184 - val_loss: 1.6050
Epoch 19/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 5s 37ms/step - acc: 0.9532 - loss: 0.1388 - val_acc: 0.7407 - val_loss: 1.4360
Epoch 20/20
 125/125 ━━━━━━━━━━━━━━━━━━━━ 5s 37ms/step - acc: 0.9519 - loss: 0.1388 - val_acc: 0.7309 - val_loss: 1.5327

<keras.src.callbacks.history.History at 0x7fbf50e6b910>

导出端到端模型


现在,我们可能想导出一个模型对象,它的输入是任意长度的字符串,而不是索引序列。这将大大提高模型的可移植性,因为你不必担心输入预处理管道。

我们的矢量器实际上是 Keras 层,因此非常简单:

string_input = keras.Input(shape=(1,), dtype="string")
x = vectorizer(string_input)
preds = model(x)
end_to_end_model = keras.Model(string_input, preds)

probabilities = end_to_end_model(
    keras.ops.convert_to_tensor(
        [["this message is about computer graphics and 3D modeling"]]
    )
)

print(class_names[np.argmax(probabilities[0])])
comp.graphics

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Unity】为小球添加爆发力往前移动的代码

代码里的几个变量都需要在场景中提前创建好并赋值 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Shotobjt : MonoBehaviour {// 点击按钮&#xff0c;克隆一个prefab&#xff0c;然后给这个克隆后的对象添加往前方的力publi…

TCP/UDP通信中的部分函数

UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;和TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是互联网协议套件中最常用的两种传输层协议&#xff0c;它们负责在互联网中端到端地传输数据。尽管它们服务…

链表常见OJ题

目录 题目一&#xff1a;移除链表元素 &#xff08;1&#xff09;题目链接 &#xff08;2&#xff09;题目要求 &#xff08;3&#xff09;题解 题目二&#xff1a;反转链表 &#xff08;1&#xff09;题目链接 &#xff08;2&#xff09;题目要求​编辑 &#xff08;3…

【PostgreSQL里的子查询解析】

什么是子查询&#xff1f; 子查询是一种嵌套在其他SQL查询中的查询方式&#xff0c;也可以称作内查询或嵌套查询。当一个查询是另一个查询的条件时&#xff0c;就称之为子查询。子查询的语法格式与普通查询相同&#xff0c;但其在查询过程中起着临时结果集的作用&#xff0c;为…

冰川秘境:全球冰川可视化大屏带你穿越冰原

在浩瀚无垠的宇宙中&#xff0c;地球以其独特的蓝色光环吸引着人们的目光。而在这颗蓝色星球上&#xff0c;冰川这一大自然的杰作&#xff0c;更是以其壮美与神秘&#xff0c;让人们心驰神往。 从阿尔卑斯山脉的冰川到南极洲的冰盖&#xff0c;从格陵兰岛的冰山到喜马拉雅山脉的…

Visual Studio生成C++的DLL文件(最简单版)

前言 当你在使用C编写一些可重用的代码时&#xff0c;将其打包成一个动态链接库&#xff08;DLL&#xff09;可以使其更容易地被其他项目或者程序调用和使用。Visual Studio提供了一种简单的方式来生成C的DLL文件。下面是一个关于如何在Visual Studio中生成C的DLL文件的简单教…

基于ChatGPT 和 OpenAI 模型的现代生成式 AI

书籍&#xff1a;Modern Generative AI with ChatGPT and OpenAI Models: Leverage the capabilities of OpenAIs LLM for productivity and innovation with GPT3 and GPT4 作者&#xff1a;Valentina Alto 出版&#xff1a;Packt Publishing 书籍下载-《基于ChatGPT 和 Op…

【Unity】 HTFramework框架(四十八)使用Location设置Transform位置、旋转、缩放

更新日期&#xff1a;2024年5月14日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 Location定义Location复制Location变量的值复制Transform组件的Location值粘贴Location变量的值粘贴Location值到Transform组件在代码中使用Location Loc…

2.3 应用集成技术

第2章 信息技术知识 2.3 应用集成技术 2.3.1 数据库与数据仓库技术 数据库 以单一的数据源即数据库为中心进行事务处理、批处理、决策分析等各种数据处理工作操作型处理也称事务处理&#xff0c;指的是对联机数据库的日常操作&#xff0c;通常是对数据库中记录的查询和修改…

微信小程序主体变更的操作教程

小程序迁移变更主体有什么作用&#xff1f;进行小程序主体迁移变更&#xff0c;那可是益处多多呀&#xff01;比方说&#xff0c;能够解锁更多权限功能&#xff1b;在公司变更或注销时&#xff0c;还能保障账号的正常使用&#xff1b;此外&#xff0c;收购账号后&#xff0c;也…

Nat Plants | 植物抽核单细胞!多组学探究大豆根瘤成熟过程

发表时间&#xff1a;2023-04 发表期刊&#xff1a;Nature Plants 影响因子&#xff1a;17.352 DOI&#xff1a;10.1038/s41477-023-01387-z 研究背景 根瘤菌是亲和互作寄主植物&#xff0c;感染宿主并在根部形成共生器官根瘤&#xff0c;具有固氮…

vue3中通过自定义指令实现loading加载效果

前言 在现代Web开发中&#xff0c;提升用户体验一直是开发者们追求的目标之一。其中&#xff0c;一个常见的场景就是在用户与应用程序进行交互时&#xff0c;特别是当进行异步操作时&#xff08;如网络请求&#xff09;&#xff0c;为用户提供即时的反馈&#xff0c;避免用户因…

docker实验

1.Docker安装部署 &#xff08;1&#xff09;.关闭防火墙 &#xff08;2&#xff09;.更新源 &#xff08;3&#xff09;设置Docker仓库 &#xff08;4&#xff09;启动docker &#xff08;5&#xff09;查看版本&#xff1a; 2.Docker pull 容器并运行服务&#xff1b; 拉取…

项目9-网页聊天室1(注册+Bycrpt加密)

1.准备工作 1.1.前端页面展示 1.2 数据库的建立 我们通过注册页面&#xff0c;考虑如何设计用户表数据库。 用户id&#xff0c;userId用户名&#xff0c;唯一&#xff0c;username用户密码&#xff0c;password&#xff08;包括密码和确认密码ensurePssword【数据库没有该字段…

PXI/PXIe规格 A429/717 航电总线适配卡

A429是一款标准的PXI/PXIe1规格的多协议总线适配卡。该产品最多支持36个A429通道&#xff0c;或32个A429通道加4个A717通道&#xff0c;每个A429和A717通道可由软件配置成接收或发送&#xff0c;可满足A429总线和A717总线的通讯、测试和数据分析等应用需求。 该产品的每个A429通…

儿童身高成长:关注每一厘米的成长

引言&#xff1a; 儿童的身高发育是家长和教育者普遍关注的问题&#xff0c;它不仅关乎孩子的外貌形象&#xff0c;更与孩子的健康成长密切相关。本文将深入探讨儿童身高的注意事项&#xff0c;为家长和教育者提供科学的指导&#xff0c;帮助孩子健康成长。 1. 身高发育的基本知…

BM11 链表相加(二)

描述 假设链表中每一个节点的值都在 0 - 9 之间&#xff0c;那么链表整体就可以代表一个整数。 给定两个这种链表&#xff0c;请生成代表两个整数相加值的结果链表。 数据范围&#xff1a;0≤&#x1d45b;,&#x1d45a;≤10000000≤n,m≤1000000&#xff0c;链表任意值 0≤…

前端面试:项目细节|项目重难点|已工作|做分享

面试官提问&#xff1a;分享一个项目中记忆比较深刻的需求&#xff1f;说说你是怎么解决的&#xff1f;解决过程有没有遇到什么困难&#xff1f; 答&#xff1a;我的回答&#xff08;我分点写思路&#xff0c;便于大家观看&#xff09;&#xff1a; &#xff08;1&#xff09…

C语言例题41、八进制转换为十进制

#include<stdio.h>void main() {int x;printf("请输入一个8进制整数&#xff1a;");scanf("%o", &x);printf("转换成十进制后的整数为%d\n", x); }运行结果&#xff1a; 本章C语言经典例题合集&#xff1a;http://t.csdnimg.cn/FK0Qg…

Web3时代的技术革新:区块链与人工智能的融合

随着科技的飞速发展&#xff0c;区块链和人工智能作为两大颠覆性技术正呈现出日益紧密的融合趋势。在Web3时代&#xff0c;这种融合将推动技术革新&#xff0c;引领着我们进入全新的数字时代。本文将深入探讨区块链与人工智能的融合&#xff0c;探索其在各个领域的应用前景和挑…