Python深度学习基于Tensorflow(16)基于Transformer的对话实例

news2025/6/25 19:56:01

文章目录

      • 基础数据清洗
      • 数据生成词汇表
      • 定义分词器并制作数据集
      • 构建Transformer模型并训练
      • 模型推理

Tensorflow 的核心就是注意力机制,在之前详细的介绍过,具体可以看这个:Python深度学习基于Tensorflow(9)注意力机制_tensorflow的各种注意力机制python代码-CSDN博客

在这里插入图片描述

基础数据清洗

如果有其他数据可以忽略这一步,这里的数据效果出乎意料的差;

书中不知道是哪里来的数据集,并没有介绍,对话数据放在两个文件中,一个文件路径 ./data/movie_lines.txt,另一个文件路径 ./data/movie_conversations.txt

import os

def base_process(max_nums=50000, return_lines=False):
    """max_nums 用来限制 conversation pair 个数、 return_lines 用来构建词表"""
    ## 生成 id 与 line 的字典
    id2line = {}
    with open('./data/movie_lines.txt', errors='ignore') as f:
        lines = f.readlines()
    for line in lines:
        parts = line.replace('\n', '').split(' +++$+++ ')
        id2line[parts[0]] = parts[4]
    
    ## 利用 id2line 查找 conversation ,并将 conversation 依次遍历生成 line_pair
    X, y = [], []
    with open('./data/movie_conversations.txt', 'r') as file:
        lines = file.readlines()
    for line in lines:
        parts = line.replace('\n', '').split(' +++$+++ ')
        conversation = [line[1:-1] for line in parts[3][1:-1].split(', ')]
        for ix in range(len(conversation)-1):
            X.append(id2line[conversation[ix]].replace('-', ''))
            y.append(id2line[conversation[ix+1]].replace('-', ''))
        if len(X) > max_nums:
            break

    if return_lines == True:
        return X, y, list(id2line.values())
    else:
        return X, y

# return_lines 用来构建词表
X, y, lines  = base_process(return_lines=True)

# 数据展示
for i in range(5):
    print(f'inputs: {X[i]} \noutputs: {y[i]} \n')

得到数据展示,简直了,牛头不对马嘴…

inputs: Can we make this quick?  Roxanne Korrine and Andrew Barrett are having an incredibly horrendous public break up on the quad.  Again. 
outputs: Well, I thought we'd start with pronunciation, if that's okay with you. 

inputs: Well, I thought we'd start with pronunciation, if that's okay with you. 
outputs: Not the hacking and gagging and spitting part.  Please. 

inputs: Not the hacking and gagging and spitting part.  Please. 
outputs: Okay... then how 'bout we try out some French cuisine.  Saturday?  Night? 

inputs: You're asking me out.  That's so cute. What's your name again? 
outputs: Forget it. 

inputs: No, no, it's my fault  we didn't have a proper introduction  
outputs: Cameron.

数据生成词汇表

代码如下

import tensorflow as tf
import tensorflow_text as tf_text
from tensorflow_text.tools.wordpiece_vocab import bert_vocab_from_dataset as bert_vocab

dataset = tf.data.Dataset.from_tensor_slices((X, y))
lines_dataset = tf.data.Dataset.from_tensor_slices((lines))


## 构建词表,这一步耗时较久 大概时间为2min 21s
bert_vocab_args = dict(
    vocab_size = 8000, # The target vocabulary size
    reserved_tokens = ["[PAD]", "[UNK]", "[START]", "[END]"], # Reserved tokens that must be included in the vocabulary
    bert_tokenizer_params=dict(lower_case=True), # Arguments for `text.BertTokenizer`
    learn_params={}, # Arguments for `wordpiece_vocab.wordpiece_tokenizer_learner_lib.learn`
)
vocab = bert_vocab.bert_vocab_from_dataset(dataset=lines_dataset, **bert_vocab_args)

# print(vocab[: 5], len(vocab))
# ['[PAD]', '[UNK]', '[START]', '[END]', '!'] 7881

得到 vocab 后,定义函数将 vocab 写入文件

def write_vocab_file(filepath, vocab):
    with open(filepath, 'w') as f:
        for token in vocab:
            print(token, file=f)

## 保存 vocab 到文件 vocab.txt
write_vocab_file('vocab.txt', vocab)

得到词汇表,vocab.txt

定义分词器并制作数据集

分词器定义可以看这篇:Tokenizing with TF Text | TensorFlow (google.cn);执行代码如下

@tf.function
def process_batch_strings(inputs, outputs, left_pad=tf.constant([2], dtype=tf.int64), right_pad=tf.constant([3], dtype=tf.int64)):
    """ 这里 left_pad 添加 [START] 其 ids 默认为 2 同样的 [END] 其 ids 默认为3 """
    inputs = tokenizer.tokenize(inputs).merge_dims(-2, -1)  # 对 RaggedTensor 操作 flat_values 等价于 .merge_dims(-2, -1).merge_dims(-2, -1)
    
    # 在 sequence 开头和结尾添加东西 如 tf.constant([0], dtype=tf.int64)
    inputs = tf_text.pad_along_dimension(inputs, axis=-1, left_pad=left_pad, right_pad=right_pad)
    inputs = tf_text.pad_model_inputs(inputs, max_seq_length=128, pad_value=0)
    
    outputs = tokenizer.tokenize(outputs).merge_dims(-2, -1) # 对 RaggedTensor 操作 flat_values 等价于 .merge_dims(-2, -1).merge_dims(-2, -1)
    
    # 在 sequence 开头和结尾添加东西 如 tf.constant([0], dtype=tf.int64)
    outputs = tf_text.pad_along_dimension(outputs, axis=-1, left_pad=left_pad, right_pad=right_pad)
    outputs = tf_text.pad_model_inputs(outputs, max_seq_length=128, pad_value=0)

    # inputs 和 outputs 由 ids 和 mask 组成,由于 embedding 有 mask_zero优化 这里只提取出 ids 
    return (inputs[0], outputs[0][:, :-1]), outputs[0][:,  1:]

# tokenizer 定义分词器
tokenizer = tf_text.BertTokenizer('vocab.txt', **dict(lower_case=True))

# 处理数据集
dataset = dataset.batch(128).map(process_batch_strings)

# dataset.take(1).get_single_element()
# ((<tf.Tensor: shape=(16, 128), dtype=int64, numpy=
#   array([[  2, 276, 259, ...,   0,   0,   0],
#          [  2, 306,  14, ...,   0,   0,   0],
#          [  2, 274, 250, ...,   0,   0,   0],
#          ...,
#          [  2, 253,  10, ...,   0,   0,   0],
#          [  2, 297, 260, ...,   0,   0,   0],
#          [  2, 286,  16, ...,   0,   0,   0]], dtype=int64)>,
#   <tf.Tensor: shape=(16, 127), dtype=int64, numpy=
#   array([[   2,  306,   14, ...,    0,    0,    0],
#          [   2,  274,  250, ...,    0,    0,    0],
#          [   2,  351,   16, ...,    0,    0,    0],
#          ...,
#          [   2,  599, 1322, ...,    0,    0,    0],
#          [   2,  306,   14, ...,    0,    0,    0],
#          [   2,  322,   33, ...,    0,    0,    0]], dtype=int64)>),
#  <tf.Tensor: shape=(16, 127), dtype=int64, numpy=
#  array([[ 306,   14,   47, ...,    0,    0,    0],
#         [ 274,  250, 5477, ...,    0,    0,    0],
#         [ 351,   16,   16, ...,    0,    0,    0],
#         ...,
#         [ 599, 1322,   16, ...,    0,    0,    0],
#         [ 306,   14,  286, ...,    0,    0,    0],
#         [ 322,   33,    3, ...,    0,    0,    0]], dtype=int64)>)

构建Transformer模型并训练

这里使用三角绝对位置编码,采取旋转位置编码的方式进行构建模型,由于 tensorflow 没有旋转位置编码的类,这里定义一个 RotaryEmbedding

class RotaryEmbedding(tf.keras.layers.Layer):
    def __init__( self, max_wavelength=10000, scaling_factor=1.0, **kwargs):
        super().__init__(**kwargs)
        self.max_wavelength = max_wavelength
        self.scaling_factor = scaling_factor
        self.built = True

    def call(self, inputs, start_index=0, positions=None):
        cos_emb, sin_emb = self._compute_cos_sin_embedding(inputs, start_index, positions)
        output = self._apply_rotary_pos_emb(inputs, cos_emb, sin_emb)
        return output

    def _apply_rotary_pos_emb(self, tensor, cos_emb, sin_emb):
        x1, x2 = tf.split(tensor, 2, axis=-1)
        half_rot_tensor = tf.stack((-x2, x1), axis=-2)
        half_rot_tensor = tf.reshape(half_rot_tensor, tf.shape(tensor))
        return (tensor * cos_emb) + (half_rot_tensor * sin_emb)

    def _compute_positions(self, inputs, start_index=0):
        seq_len = tf.shape(inputs)[1]
        positions = tf.range(seq_len, dtype="float32")
        return positions + tf.cast(start_index, dtype="float32")

    def _compute_cos_sin_embedding(self, inputs, start_index=0, positions=None):
        feature_axis = len(inputs.shape) - 1
        sequence_axis = 1

        rotary_dim = tf.shape(inputs)[feature_axis]
        inverse_freq = self._get_inverse_freq(rotary_dim)

        if positions is None:
            positions = self._compute_positions(inputs, start_index)
        else:
            positions = tf.cast(positions, "float32")

        positions = positions / tf.cast(self.scaling_factor, "float32")
        freq = tf.einsum("i,j->ij", positions, inverse_freq)
        embedding = tf.stack((freq, freq), axis=-2)

        # 这里 *tf.shape(freq)[:-1] 使用 model.fit 的话无法计算
        # embedding = tf.reshape(embedding, (*tf.shape(freq)[:-1], tf.shape(freq)[-1] * 2))
        embedding = tf.reshape(embedding, (tf.shape(freq)[0], tf.shape(freq)[-1] * 2))

        if feature_axis < sequence_axis:
            embedding = tf.transpose(embedding)
        for axis in range(len(inputs.shape)):
            if axis != sequence_axis and axis != feature_axis:
                embedding = tf.expand_dims(embedding, axis)

        cos_emb = tf.cast(tf.cos(embedding), self.compute_dtype)
        sin_emb = tf.cast(tf.sin(embedding), self.compute_dtype)
        return cos_emb, sin_emb

    def _get_inverse_freq(self, rotary_dim):
        freq_range = tf.divide(tf.range(0, rotary_dim, 2, dtype="float32"),tf.cast(rotary_dim, "float32"))
        inverse_freq = 1.0 / (self.max_wavelength**freq_range)
        return inverse_freq

在注意力机制中融合 RotaryEmbedding 得到 MultiHeadAttention

class MultiHeadAttention(tf.keras.layers.Layer):
    def __init__(self, num_heads, d_model, with_rotary=True):
        super(MultiHeadAttention, self).__init__()
        self.num_heads = num_heads
        self.d_model = d_model
        self.with_rotary = with_rotary

        ## 判断能否被整除
        assert self.d_model % self.num_heads == 0

        ## 定义需要用到的 layer
        self.query_dense = tf.keras.layers.Dense(self.d_model)
        self.key_dense = tf.keras.layers.Dense(self.d_model)
        self.value_dense = tf.keras.layers.Dense(self.d_model)
        self.output_dense = tf.keras.layers.Dense(self.d_model)

        self.rotary_query = RotaryEmbedding()
        self.rotary_key = RotaryEmbedding()
    
        # self.rotary_query = keras_nlp.layers.RotaryEmbedding()
        # self.rotary_key = keras_nlp.layers.RotaryEmbedding()
        
    
    def call(self, x_query, x_key, x_value, use_casual_mask=False):
        
        if self.with_rotary:
            query = self._split_heads(self.rotary_query(self.query_dense(x_query)))
            key = self._split_heads(self.rotary_key(self.key_dense(x_key)))
        else:
            query = self._split_heads(self.query_dense(x_query))
            key = self._split_heads(self.key_dense(x_key))
            
        value = self._split_heads(self.value_dense(x_value))
        output, attention_weights = self._scaled_dot_product_attention(query, key, value, use_casual_mask)
        output = tf.keras.layers.Lambda(lambda output: tf.transpose(output, perm=[0, 2, 1, 3]))(output)
        output = tf.keras.layers.Lambda(lambda output: tf.reshape(output, [tf.shape(output)[0], -1, self.d_model]))(output)
        output = self.output_dense(output)
        return output

    def _split_heads(self, x):
        # x = tf.reshape(x, [tf.shape(x)[0], -1, self.num_heads, self.d_model / self.num_heads])
        # x = tf.transpose(x, perm=[0, 2, 1, 3])
        x = tf.keras.layers.Lambda(lambda x: tf.reshape(x, [tf.shape(x)[0], -1, self.num_heads, self.d_model // self.num_heads]))(x)
        x = tf.keras.layers.Lambda(lambda x: tf.transpose(x, perm=[0, 2, 1, 3]))(x)
        return x

    def _scaled_dot_product_attention(self, query, key, value, use_casual_mask):
        dk = tf.cast(tf.shape(key)[-1], tf.float32)
        scaled_attention_logits = tf.matmul(query, key, transpose_b=True) / tf.math.sqrt(dk)

        if use_casual_mask:
            casual_mask = 1 - tf.linalg.band_part(tf.ones_like(scaled_attention_logits), -1, 0)
            scaled_attention_logits += casual_mask * -1e9

        attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1)
        output = tf.matmul(attention_weights, value)
        return output, attention_weights

定义前馈神经网络层 FeedForward

class FeedForward(tf.keras.layers.Layer):
    def __init__(self, d_model):
        super(FeedForward, self).__init__()
        self.dense_1 = tf.keras.layers.Dense(4 * 2 * d_model // 3)
        self.dense_2 = tf.keras.layers.Dense(d_model)
        self.dense_3 = tf.keras.layers.Dense(4 * 2 * d_model // 3)

    def call(self, x):
        x = self.dense_2(tf.nn.silu(self.dense_1(x)) * self.dense_3(x))
        return x

再定义 RMSNorm 代替 LayerNorm 加快计算速度;

class RMSNorm(tf.keras.layers.Layer):
    def __init__(self, d_model, eps=1e-6):
        super(RMSNorm, self).__init__()
        self.eps = eps
        self.gamma = self.add_weight(shape=d_model, initializer='ones', trainable=True)
        
    def call(self, x):
        x = self._norm(x)
        output = x * self.gamma
        return output
    
    def _norm(self, x):
        return x * tf.math.rsqrt(tf.reduce_mean(tf.pow(x, 2), axis=-1, keepdims=True) + self.eps)

构建 EncoderLayerEncoder

class EncoderLayer(tf.keras.layers.Layer):
    def __init__(self, num_heads, d_model):
        super(EncoderLayer, self).__init__()
        self.mha = MultiHeadAttention(num_heads, d_model, with_rotary=True)
        self.ffn = FeedForward(d_model)
        self.rms_mha = RMSNorm(d_model)
        self.rms_ffn = RMSNorm(d_model)

    def call(self, x):
        
        ## attention 层计算
        x = self.rms_mha(x)
        x = x + self.mha(x, x, x, use_casual_mask=False)
        
        ## feedforward 层计算
        x = self.rms_ffn(x)
        x = x + self.ffn(x)

        return x


class Encoder(tf.keras.layers.Layer):
    def __init__(self, encoder_layer_nums, vocabulary_size, num_heads, d_model):
        super(Encoder, self).__init__()
        self.embedding = tf.keras.layers.Embedding(vocabulary_size, d_model, mask_zero=True)
        self.encoder_layers = [EncoderLayer(num_heads, d_model) for _ in range(encoder_layer_nums)]

    def call(self, x):
        x = self.embedding(x)
        for encoder_layer in self.encoder_layers:
            x = encoder_layer(x)
        return x

同样的,DecoderLayerDecoder

class DecoderLayer(tf.keras.layers.Layer):
    def __init__(self, num_heads, d_model):
        super(DecoderLayer, self).__init__()
        self.mha_1 = MultiHeadAttention(num_heads, d_model, with_rotary=True)
        self.mha_2 = MultiHeadAttention(num_heads, d_model, with_rotary=True)
        self.ffn = FeedForward(d_model)
        self.rms_mha_1 = RMSNorm(d_model)
        self.rms_mha_2 = RMSNorm(d_model)
        self.rms_ffn = RMSNorm(d_model)

    def call(self, x, encoder_output):
        
        ## mask attention 层计算
        x = self.rms_mha_1(x)
        x = x + self.mha_1(x, x, x, use_casual_mask=True)

        ## attention 层计算
        x = self.rms_mha_2(x)
        x = x + self.mha_2(x, encoder_output, encoder_output, use_casual_mask=False)
        
        ## feedforward 层计算
        x = self.rms_ffn(x)
        x = x + self.ffn(x)

        return x


class Decoder(tf.keras.layers.Layer):
    def __init__(self, decoder_layer_nums, vocabulary_size, num_heads, d_model):
        super(Decoder, self).__init__()
        self.embedding = tf.keras.layers.Embedding(vocabulary_size, d_model, mask_zero=True)
        self.decoder_layers = [DecoderLayer(num_heads, d_model) for _ in range(decoder_layer_nums)]

    def call(self, x, encoder_output):
        x = self.embedding(x)
        for decoder_layer in self.decoder_layers:
            x = decoder_layer(x, encoder_output)
        return x

建立 Transformer 模型

class Transformer(tf.keras.Model):
    def __init__(self, decoder_layer_nums, encoder_layer_nums, vocabulary_size, num_heads, d_model):
        super(Transformer, self).__init__()
        self.encoder = Encoder(encoder_layer_nums, vocabulary_size, num_heads, d_model)
        self.decoder = Decoder(decoder_layer_nums, vocabulary_size, num_heads, d_model)
        self.final_dense = tf.keras.layers.Dense(vocabulary_size, activation='softmax')

    def call(self, x):
        x1, x2 = x[0], x[1]
        x1 = self.encoder(x1)
        x2 = self.decoder(x2, x1)
        output = self.final_dense(x2)
        return output

定义调度器类,使用 warmup

class CustomSchedule(tf.keras.optimizers.schedules.LearningRateSchedule):
    def __init__(self, d_model, warmup_steps=4000):
        super().__init__()
        
        self.d_model = d_model
        self.d_model = tf.cast(self.d_model, tf.float32)
        
        self.warmup_steps = warmup_steps
    
    def __call__(self, step):
        step = tf.cast(step, dtype=tf.float32)
        arg1 = tf.math.rsqrt(step)
        arg2 = step * (self.warmup_steps ** -1.5)
        
        return tf.math.rsqrt(self.d_model) * tf.math.minimum(arg1, arg2)

定义模型并开始学习

decoder_layer_nums=2
encoder_layer_nums=2
vocabulary_size=len(vocab)
num_heads=8
d_model=256

learning_rate = CustomSchedule(d_model)
optimizer = tf.keras.optimizers.Adam(learning_rate, beta_1=0.9, beta_2=0.98, epsilon=1e-9)

model = Transformer(decoder_layer_nums, encoder_layer_nums, vocabulary_size, num_heads, d_model)

model.compile(
    loss=tf.keras.losses.sparse_categorical_crossentropy,
    optimizer=optimizer,
    metrics=['accuracy']
)

## 开始训练
history = model.fit(dataset, epochs=10)

# Epoch 1/10
# 391/391 [==============================] - 43s 94ms/step - loss: 2.3794 - accuracy: 0.8041
# Epoch 2/10
# 391/391 [==============================] - 37s 94ms/step - loss: 0.6215 - accuracy: 0.9024
# Epoch 3/10
# 391/391 [==============================] - 37s 95ms/step - loss: 0.5656 - accuracy: 0.9060
# Epoch 4/10
# 391/391 [==============================] - 37s 95ms/step - loss: 0.5365 - accuracy: 0.9077
# Epoch 5/10
# 391/391 [==============================] - 37s 95ms/step - loss: 0.5097 - accuracy: 0.9095
# Epoch 6/10
# 391/391 [==============================] - 37s 96ms/step - loss: 0.4812 - accuracy: 0.9119
# Epoch 7/10
# 391/391 [==============================] - 37s 95ms/step - loss: 0.4549 - accuracy: 0.9145
# Epoch 8/10
# 391/391 [==============================] - 37s 94ms/step - loss: 0.4335 - accuracy: 0.9166
# Epoch 9/10
# 391/391 [==============================] - 37s 94ms/step - loss: 0.4162 - accuracy: 0.9183
# Epoch 10/10
# 391/391 [==============================] - 37s 95ms/step - loss: 0.4047 - accuracy: 0.9192

模型推理

定义推理类 Inference

class Inference(tf.Module):
    def __init__(self, model, tokenizer):
        self.model = model
        self.tokenizer = tokenizer

    def __call__(self, x, max_length=128):
        from rich.progress import track
        x = self.tokenizer.tokenize(x).flat_values

        ## 定义 start 和 end
        start = tf.constant([2], dtype=tf.int64)
        end = tf.constant([3], dtype=tf.int64)
        x = tf_text.pad_along_dimension(x, axis=-1, left_pad=start, right_pad=end)[tf.newaxis, :]

        # 定义 TensorArray 要记得使用write需要赋值 zz=zz.write()
        outputs = tf.TensorArray(tf.int64, size=0, dynamic_size=True)
        outputs = outputs.write(0, start)

        for i in track(tf.range(max_length)):
            temp = tf.transpose(outputs.stack())
            temp = model.predict((x, temp), verbose=0)[:, -1:, :]
            output = tf.argmax(temp, axis=-1)[0]
            if output == end:
                break
            else:
                outputs = outputs.write(outputs.size(), output)

        outputs = outputs.stack()
        outputs = tf.transpose(outputs)
        x = tf.strings.reduce_join(self.tokenizer.detokenize(outputs).flat_values[1:], separator=' ').numpy().decode('utf-8')
        return x

初始化类,并开始推理

infernce = Inference(model, tokenizer)
infernce('what do you want me to do?')
# "i don ' t want to be a good idea ."

可以看到牛头不对马嘴,数据是一个原因,训练层数是一个原因

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

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

相关文章

解决浏览器缩放的时候,重新设置滚动条的位置,使页面滚动条固定悬浮在页面底部

项目场景&#xff1a; 浏览器调试页面兼容页面时&#xff0c;缩放页面宽度&#xff0c;整体超出时滚动条出现在页面最底部&#xff0c;不是悬浮在页面下面&#xff0c;只有滚动到最底部才出现&#xff0c;需要的是悬浮在页面底部&#xff0c;不是滚动到最下面才出现 解决方案…

二维数组的遍历

旋转图像 class Solution {public void rotate(int[][] matrix) {for(int i0;i<matrix.length;i){for(int ji1;j<matrix[0].length;j){int tempmatrix[i][j];matrix[i][j]matrix[j][i];matrix[j][i]temp;}}for(int[] arr:matrix){reverse(arr);}}void reverse(int[] arr)…

Ant-design-vue开源项目介绍、应用场景、组件有哪些

文章目录 一、Ant-design-vue项目介绍二、Ant-design-vue项目特点三、Ant-design-vue应用场景四、Ant-design-vue有哪些组件五、Ant-design-vue案例代码1. 后台管理系统登录页面的例子2. Table组件使用案例 开源项目地址 一、Ant-design-vue项目介绍 Ant-design-vue 是一个基于…

java面试题:springMVC的执行流程

请求到达前端控制器DispatcherServlet&#xff0c;该组件是SpringMVC的核心组件&#xff0c;负责接收所有的请求。 DispatcherServlet根据请求中的URL和HandlerMapping找到对应的Controller对象&#xff0c;HandlerMapping是一个接口&#xff0c;定义了请求的URL和对应的Contro…

刺客信条找不到emp.dll怎么解决?emp.dll缺失的解决方法解析

emp.dll 是一个动态链接库文件&#xff0c;它在Windows操作系统中扮演着重要的角色。这个文件包含了多个函数和接口&#xff0c;允许其他程序调用这些功能来实现对多媒体设备的控制和管理。根据搜索结果&#xff0c;emp.dll 主要负责以下功能&#xff1a; 多媒体设备管理&…

进阶篇03——SQL优化

insert 优化 主键优化 不好做笔记&#xff0c;但是挺重要的&#xff0c;留个视频链接&#xff1a;主键优化 order by 优化 视频链接&#xff1a;order by 优化 group by 优化 放视频&#xff08;好吧&#xff0c;这篇文章感觉还是看视频容易懂一点&#xff09;&#xff1a;…

一文了解JVM(中)

HotSpot 虚拟机对象探秘 对象的创建 Header解释使用 new 关键字调用了构造函数使用 Class 的 newInstance 方法调用了构造函数使用 Constructor 类的newInstance 方法调用了构造函数使用 clone 方法没有调用构造函数使用反序列化没有调用构造函数说到对象的创建,首先让我们看…

45.Python-web框架-Django - 开始建立第一个项目

目录 1.django是什么&#xff1f; 2.Pycharm 社区版&#xff0c;还是专业版&#xff1f; 3.开始django&#xff0c;Pycharm专业版 创建一个Django项目 运行一个Django项目 运行方法一&#xff0c;命令行的方式 运行方法二&#xff0c;配置Django Server的方式 4.django尊…

编译原理:语法分析之LR分析

自底向上分析方法&#xff08;LR分析算法&#xff09;bottom-up parsing 引言. 运算符 LR(0)LR(0)的项&#xff08;构建有穷自动机的状态&#xff09;LR(0)的项目闭包&#xff08;构建有穷自动机的状态&#xff09;GOTO函数有效项目LR(0)有穷自动机的构建 SLRLR(1)LALR 引言 L…

树莓派4B学习笔记7:(Python)_TTL串口收发数据_

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日尝试使用树莓派的TTL串口进行收发数据&#xff1a; …

Web应用安全测试-业务功能滥用(二)

Web应用安全测试-业务功能滥用&#xff08;二&#xff09; 7、未验证的URL跳转 漏洞描述&#xff1a;服务端未对传入的跳转url变量进行检查和控制&#xff0c;可能导致可恶意构造任意一个恶意地址&#xff0c;诱导用户跳转到恶意网站。由于是从可信的站点跳转出去的&#xff…

无线MODBUS通讯模块在供水系统中的应用

一、项目背景 我国是人口大国、农业大国&#xff0c;同时也是贫水大国。由于大量工业废水污染了部分河流、地表的浅层水资源&#xff0c;并且有逐年加重的趋势&#xff0c;再加上农业、绿化等灌溉对水资源的大量消耗&#xff0c;这些因素综合作用进一步加剧了我国水资源紧缺的…

计算机网络:网络层 - IPv6

计算机网络&#xff1a;网络层 - IPv6 IPv6 数据报IPv6 地址冒号十六进制记法地址分类 IPv4 到 IPv6 过渡双栈协议隧道技术 IPv6 是互联网协议的最新版本&#xff0c;它被设计用来取代现有的 IPv4 协议。这是因为 IPv4 存在一些根本性的限制&#xff0c;而 IPv6 则可以解决这些…

Burp Suite使用及BruteForc_test靶场实战

简介 Burp Suite是用于攻击和测试Web应用程序安全性的集成平台&#xff0c;包含多个协同工作的工具&#xff0c;支持信息共享与复杂攻击。设计有加速攻击流程的接口&#xff0c;所有工具共享强大框架&#xff0c;处理HTTP消息、持久性、认证、代理、日志和警报。主要用于安全性…

【数据结构】【版本1.1】【线性时代】——单链表

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、顺序表的问题二、链表的概念三、单链表的模拟实现3.1 定义3.2 打印3.3 创建新节点3.4 头插3.5 尾插3…

2-3 基于matlab的NSCT-PCNN融合和创新算法(NSCT-ML-PCNN )图像融合

基于matlab的NSCT-PCNN融合和创新算法&#xff08;NSCT-ML-PCNN &#xff09;图像融合。NSSCTest.m文件&#xff1a;用于查看利用NSSC算法分解出的图像并保存。其中的nlevel可调test.m文件&#xff1a;用于产生融合结果&#xff0c;其中一个参数需要设置&#xff1a;Low_Coeffs…

DTU在城市智慧供热上的应用:引领供热行业的智能化革新

随着城市化的快速推进和人们对舒适生活需求的日益增长&#xff0c;供热系统作为城市基础设施的重要组成部分&#xff0c;其智能化、高效化的发展已成为必然趋势。在这一进程中&#xff0c;DTU&#xff08;Data Transfer Unit&#xff0c;数据传输单元&#xff09;以其独特的优势…

Java 反射机制 -- Java 语言反射的概述、核心类与高级应用

大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 010 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进一步完善自己对整个 Java 技术体系来充实自…

113.网络游戏逆向分析与漏洞攻防-邮件系统数据分析-结构体数据更新思路分析

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

12_YouOnlyLookOnce(YOLOv3)新一代实时目标检测技术

1.1 回顾V1和V2 V1&#xff1a;05_YouOnlyLookOnce(YOLOV1)目标检测领域的革命性突破-CSDN博客 V2&#xff1a;07_YouOnlyLookOnce(YOLOv2)Better&#xff0c;Faster&#xff0c;Stronger-CSDN博客 1.2 简介 YOLOv3&#xff08;You Only Look Once version 3&#xff09;是…