【自然语言处理】文本信息提取器-RNN_rnn 文本特征提取-程序员宅基地

技术标签: nlp  深度学习  自然语言处理  

本文主要内容

  • 简略介绍循环神经网络(RNN, Recurrent Neural Network),其中涉及单层RNN结构、多层RNN结构、双向RNN结构、双向RNN+Attention结构
  • 使用RNN进行文本分类任务,并给出模型的定义代码
  • 本文代码【 https://github.com/540117253/Chinese-Text-Classification 】

一、RNN概述

  循环神经网络RNN是特指一类专用于处理序列数据的模型,目前主流的RNN单元有LSTM(Long Short-Term Memory)和GRU(Gated Recurrent Unit)两种。相比最原始的RNN单元,LSTM通过增加记忆单元来缓解长序列数据训练时所产生的梯度消失问题,而GRU则是一种基于LSTM进行改进以进一步提升训练速度的变体单元。下文依次介绍单层RNN结构、多层RNN结构、双向RNN结构,这三种网络结构都可以根据实际需求来任意选择RNN单元(LSTM或GRU)。

1.1 单层RNN结构

在这里插入图片描述

图1 RNN(以LSTM为例)处理过程示意图

   假设给定一个句子 S = { w t } t = 1 N S=\{w_t\}^N_{t=1} S={ wt}t=1N ,其中句子的长度为 N N N个单词,句子中第 t t t个单词为 w t w_t wt。在RNN处理前,需要先将每个单词 w t w_t wt映射为一个向量 x t x_t xt进行表达,即得到 S = { x t } t = 1 N S=\{x_t\}^N_{t=1} S={ xt}t=1N。在RNN的处理过程中,是依照从前往后的次序进行处理,即从第一个单词 x 1 x_1 x1到第 t t t个单词 x t x_t xt的次序进行运算。图1以LSTM作为基本单元为例(GRU单元同理),展示了RNN处理一个句子 S = { x t } t = 1 N S=\{x_t\}^N_{t=1} S={ xt}t=1N的整体示意图。处理过程的公式描述如下:

f t = σ ( W f [ h t − 1 , x t ] + b f ) f_t=\sigma{(W_f[h_{t-1},x_t]+b_f)} ft=σ(Wf[ht1,xt]+bf)
i t = σ ( w i [ h t − 1 , x t ] ) + b i i_t=\sigma{(w_i[h_{t-1},x_t])+b_i} it=σ(wi[ht1,xt])+bi
C ~ = t a n h ( W c [ h t − 1 , x t ] + b c ) \widetilde{C}=tanh(W_c[h_{t-1},x_t]+b_c) C =tanh(Wc[ht1,xt]+bc)
C t = f t ∗ C t − 1 + i t ∗ C ~ C_t=f_t*C_{t-1}+i_t*\widetilde{C} Ct=ftCt1+itC
o t = σ ( W o [ h t − 1 , x t ] + b o ) o_t=\sigma{(W_o[h_{t-1},x_t]+b_o)} ot=σ(Wo[ht1,xt]+bo)
h t = o t ∗ t a n h ( C t ) h_t=o_t*tanh(C_t) ht=ottanh(Ct)

  上述公式描述了句子 S = { x t } t = 1 N S=\{x_t\}^N_{t=1} S={ xt}t=1N中第 t t t个单词 x t x_t xt(第 t t t个时间步的输入)得到运算结果 h t h_t ht(第 t t t个时间步的输出)的完成过程。 [ ⋅ ] [\cdot] []表示拼接操作, σ \sigma σ表示sigmoid函数, ∗ * 表示哈达玛积(Hadamard Product)。

在这里插入图片描述

图2 GRU结构示意图

  同样采用图1的结构,可以将LSTM单元替换为GRU单元,具体的GRU结构如图2所示。针对句子 S = { x t } t = 1 N S=\{x_t\}^N_{t=1} S={ xt}t=1N中第 t t t个单词 x t x_t xt,使用GRU计算出第 t t t个时间步的输出 h t h_t ht的过程可以描述为:

z t = σ ( W z [ h t − 1 , x t ] ) z_t=\sigma{(W_z[h_{t-1},x_t])} zt=σ(Wz[ht1,xt])
r t = σ ( w r [ h t − 1 , x t ] ) r_t=\sigma{(w_r[h_{t-1},x_t])} rt=σ(wr[ht1,xt])
h t ^ = t a n h ( W [ r t ∗ h t − 1 , x t ] ) \widehat{h_t}=tanh(W[r_t*h_{t-1},x_t]) ht =tanh(W[rtht1,xt])
h t = ( 1 − z t ) ∗ h t − 1 + z t ∗ h ^ t h_t=(1-z_t)*h_{t-1}+z_t*\widehat{h}_t ht=(1zt)ht1+zth t

1.2 多层RNN结构

在这里插入图片描述

图3 多层RNN结构(以LSTM为例)

  为了更全面细致地提取每个单词的信息,同样可以采取加深网络结构的方式堆叠多个RNN单元构建深层网络。多层RNN与单层RNN相似,同样是采取将一个句子 S = { x t } t = 1 N S=\{x_t\}^N_{t=1} S={ xt}t=1N从前往后的次序进行处理。与单层RNN的区别在于,多层RNN的第 n n n层的第 t t t个时间步的输入 x t x_t xt就是第 n − 1 n-1 n1层的第 t t t个时间步的输出 h t h_t ht。以LSTM为基本单元来搭建2层RNN为例,具体如图3所示(采用GRU为基本单元同理)。

1.3 双向RNN结构

  图4展示了双向RNN结构(以LSTM为例)。给定一个句子 S = { w t } t = 1 N S=\{w_t\}^N_{t=1} S={ wt}t=1N,其中句子的长度为 N N N个单词,句子中第 t t t个单词的向量为 w t w_t wt。双向RNN是一种RNN网络结构,其将读入的序列(这里是一个句子)从前往后和从后往前同时处理,最终将前向和后向的隐状态拼接作为最终的隐状态。

在这里插入图片描述

图4 双向RNN结构(以LSTM为例)

h t → = R N N ( h → t − 1 , w t ) \overrightarrow{h_t}=RNN(\overrightarrow{h}_{t-1}, w_t) ht =RNN(h t1,wt)
h t ← = R N N ( h ← t + 1 , w t ) \overleftarrow{h_t}=RNN(\overleftarrow{h}_{t+1},w_t) ht =RNN(h t+1,wt)
h t = [ h t → , h t ← ] h_t=[\overrightarrow{h_t},\overleftarrow{h_t}] ht=[ht ,ht ]

其中 R N N ( ) RNN() RNN()可以是LSTM单元或者是GRU单元, [ ⋅ ] [ \cdot ] []表示拼接操作。

1.4 双向RNN+Attention 结构

  Attention机制的核心思想是赋予模型更关注与任务更相关的部分,而降低对任务次相关部分的关注程度。其原理可以看作为键值查询,通过用户给定的Query,来得到序列中与任务最相关位置的权值。

  在文本分类任务中,基于RNN结构的模型都是将序列处理后的最后一个隐状态作为分类依据。由于RNN能捕获序列中的序列信息,因此最后一个隐状态包含了整个句子的信息,能够较好地应对文本分类任务。

  但是,该句子为何被模型划分为该类别,我们不能直观地进行解释。为了提高分类结果的可解释性,这里采用Attention机制对句子序列中的每个位置都计算出一个注意力得分(权值),最终权值越高的位置表明对分类结果产生越重要的影响。

  假设一个句子序列 S = { w t } t = 1 N S=\{w_t\}^N_{t=1} S={ wt}t=1N进行RNN处理后,得到的序列为 H = { h t } t = 1 N H=\{h_t\}^N_{t=1} H={ ht}t=1N,其中作为最后一个位置隐状态 h N h_N hN包含了整个序列的信息。这里 h N h_N hN将作为Query,对序列中的各个位置进行计算,得到各个位置与 h N h_N hN的关联度(与分类任务的关联度)。

q u e r y = W q h N + b q query=W_qh_N+b_q query=WqhN+bq
k e y = W k H + b k key=W_kH+b_k key=WkH+bk
a t t e n t i o n = s o f t m a x ( s u m ( W a ) t a n h ( k e y s + q u e r y ) ) attention=softmax(sum(W_a)tanh(keys+query)) attention=softmax(sum(Wa)tanh(keys+query))
o u t p u t s = a t t e n t i o n × H outputs=attention \times H outputs=attention×H

  其中 × \times ×表示 H H H按照attention得分加权求和,得到的 o u t p u t s outputs outputs继续送入全连接层进行分类结果。

1.5 基于RNN的文本分类通用结构

  在文本分类任务中,基于RNN结构的模型都是将序列处理后的最后一个隐状态 H N H_N HN作为分类依据。由于RNN能捕获序列中的序列信息,因此最后一个隐状态包含了整个句子的信息,能够较好地应对文本分类任务。

  因此,基于RNN的文本分类通用结构为:
在这里插入图片描述

二、RNN文本分类实例

2.1 数据集介绍

1. 下载地址:

  【https://github.com/skdjfla/toutiao-text-classfication-dataset 】

2. 格式:

6552431613437805063_!_102_!_news_entertainment_!_谢娜为李浩菲澄清网络谣言,之后她的两个行为给自己加分_!_佟丽娅,网络谣言,快乐大本营,李浩菲,谢娜,观众们

每行为一条数据,以_!_分割的个字段,从前往后分别是 新闻ID,分类code(见下文),分类名称(见下文),新闻字符串(仅含标题),新闻关键词

分类code与名称:

100 民生 故事 news_story
101 文化 文化 news_culture
102 娱乐 娱乐 news_entertainment
103 体育 体育 news_sports
104 财经 财经 news_finance
106 房产 房产 news_house
107 汽车 汽车 news_car
108 教育 教育 news_edu 
109 科技 科技 news_tech
110 军事 军事 news_military
112 旅游 旅游 news_travel
113 国际 国际 news_world
114 证券 股票 stock
115 农业 三农 news_agriculture
116 电竞 游戏 news_game
2.2 预训练词向量

预训练词向量使用的是,基于ACL-2018模型在百度百科训练的词向量。

下载地址:【 https://github.com/Embedding/Chinese-Word-Vectors 】

2.3 数据预处理
  1. 清除无用字符,并且进行分词处理
  2. 建立整个数据集的字典,key=word, value=词语的编号
  3. 对进行截断或补0处理,确保每条样本的长度为maxlen
  4. 序列化样本的标签,例如“体育类新闻”的类别编号为1,“娱乐类新闻”的类别编号为2
  5. 将处理好的数据转化为DataFrame格式,并保存到硬盘
2.4 模型的定义

   该小节一共分别给出多层LSTM(Multi_LSTM), 双向RNN(Bi_RNN), 双向RNN+Attention(Bi_RNN_Attention)的代码定义。

2.4.1 Multi_LSTM
'''
    Text => Multi_Layer_LSTM => Fully_Connected => Softmax
'''
class Multi_LSTM:
    def __init__(self, rnn_output_dim, num_layers, embedded_size,
                 dict_size, maxlen, label_num, learning_rate):
        
        self.droput_rate = 0.5

        # print('model_Name:', 'Multi_LSTM')
        
        self.X = tf.placeholder(tf.int32, [None, maxlen], name='input_x')
        self.Y = tf.placeholder(tf.int64, [None])
        
        self.encoder_embeddings = tf.Variable(tf.random_uniform([dict_size, embedded_size], -1, 1), trainable=False)
        encoder_embedded = tf.nn.embedding_lookup(self.encoder_embeddings, self.X)
        
        rnn_cells = [keras.layers.LSTMCell(units=rnn_output_dim) for _ in range(num_layers)]
        outputs =keras.layers.RNN(rnn_cells,return_sequences=True, return_state=False)(encoder_embedded)
        outputs = tf.nn.dropout(outputs, keep_prob = self.droput_rate)
        
        self.logits = keras.layers.Dense(label_num, use_bias=True)(outputs[:,-1]) # 取出每条文本最后一个单词的隐藏层输出
        self.probability = tf.nn.softmax(self.logits, name='probability')
        
#         self.cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = self.logits, labels = self.Y))
        self.cost = tf.nn.sparse_softmax_cross_entropy_with_logits(
                                                                    labels = self.Y, 
                                                                    logits = self.logits)
        self.cost = tf.reduce_mean(self.cost)
        self.optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(self.cost)
        self.pre_y = tf.argmax(self.logits, 1, name='pre_y')
        correct_pred = tf.equal(self.pre_y, self.Y)
        self.accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
2.4.2 Bi_RNN
'''
    Text => Bidirectional GRU or LSTM => Fully_Connected => Softmax
'''
class Bi_RNN:
    def __init__(self, rnn_output_dim, embedded_size,
                 dict_size, maxlen, label_num, learning_rate, rnn_type):
        
        self.droput_rate = 0.5

        # print('model_Name:', 'Bi_RNN')

        '''
            Process the Reviews with Bi-RNN
        '''
        def bi_rnn(rnn_type, inputs, rnn_output_dim):
            if rnn_type == 'gru':
                h = keras.layers.Bidirectional(
                              keras.layers.GRU(rnn_output_dim,return_sequences=True,unroll=True),
                              merge_mode='concat'
                       )(inputs) 

            elif rnn_type == 'lstm' :
                h = keras.layers.Bidirectional(
                              keras.layers.LSTM(rnn_output_dim,return_sequences=True,unroll=True),
                              merge_mode='concat'
                       )(inputs)
            return h # shape= (None, u_n_words, 2*rnn_output_dim) or # shape(H_d) = (None, i_n_words, 2*rnn_output_dim)
        
        self.X = tf.placeholder(tf.int32, [None, maxlen], name='input_x')
        self.Y = tf.placeholder(tf.int64, [None])
        
        self.encoder_embeddings = tf.Variable(tf.random_uniform([dict_size, embedded_size], -1, 1), trainable=False)
        encoder_embedded = tf.nn.embedding_lookup(self.encoder_embeddings, self.X)

        outputs = bi_rnn(rnn_type = rnn_type, inputs = encoder_embedded, rnn_output_dim = rnn_output_dim)
        
        outputs = tf.nn.dropout(outputs, keep_prob = self.droput_rate)
 
        self.logits = keras.layers.Dense(label_num, use_bias=True)(outputs[:,-1]) # 取出每条文本最后一个单词的隐藏层输出
        self.probability = tf.nn.softmax(self.logits, name='probability')

        self.cost = tf.nn.sparse_softmax_cross_entropy_with_logits(
                                                                    labels = self.Y, 
                                                                    logits = self.logits)
        self.cost = tf.reduce_mean(self.cost)
        self.optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(self.cost)
        self.pre_y = tf.argmax(self.logits, 1, name='pre_y')
        correct_pred = tf.equal(self.pre_y, self.Y)
        self.accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
2.4.3 Bi_RNN_Attention
'''
    Text => Bidirectional GRU or LSTM => Word_Attention => Fully_Connected => Softmax
'''
class Bi_RNN_Attention:
    def __init__(self, rnn_output_dim, embedded_size,
                 dict_size, maxlen, label_num, learning_rate, attention_size, rnn_type):
        
        self.droput_rate = 0.5

        # print('model_Name:', 'Bi_RNN_Attention')

        '''
            Process the Reviews with Bi-RNN
        '''
        def bi_rnn(rnn_type, inputs, rnn_output_dim):
            if rnn_type == 'gru':
                h = keras.layers.Bidirectional(
                              keras.layers.GRU(rnn_output_dim,return_sequences=True,unroll=True),
                              merge_mode='concat'
                       )(inputs) 

            elif rnn_type == 'lstm' :
                h = keras.layers.Bidirectional(
                              keras.layers.LSTM(rnn_output_dim,return_sequences=True,unroll=True),
                              merge_mode='concat'
                       )(inputs)
            return h # shape= (None, u_n_words, 2*rnn_output_dim) or # shape(H_d) = (None, i_n_words, 2*rnn_output_dim)
        
        self.X = tf.placeholder(tf.int32, [None, maxlen], name='input_x')
        self.Y = tf.placeholder(tf.int64, [None])
        
        self.encoder_embeddings = tf.Variable(tf.random_uniform([dict_size, embedded_size], -1, 1), trainable=False)
        encoder_embedded = tf.nn.embedding_lookup(self.encoder_embeddings, self.X)

        outputs = bi_rnn(rnn_type = rnn_type, inputs = encoder_embedded, rnn_output_dim = rnn_output_dim) # shape = [None, maxlen, rnn_output_dim] 
        
        outputs = tf.nn.dropout(outputs, keep_prob = self.droput_rate)

        '''
            Word Attention Layer
        '''
        attention_w = tf.get_variable("attention_v", [attention_size], tf.float32)
        query = keras.layers.Dense(attention_size)(tf.expand_dims(outputs[:,-1], 1)) # shape =[None, 1, attention_size]
        keys = keras.layers.Dense(attention_size)(outputs) # shape = [None, maxlen, attention_size]
        self.attention = tf.reduce_sum(attention_w * tf.tanh(keys + query), 2) # shape = [None, maxlen]
        self.attention = tf.nn.softmax(self.attention, name='attention')
        outputs = tf.squeeze(
                                tf.matmul(
                                    tf.transpose(outputs, [0, 2, 1]),tf.expand_dims(self.attention, 2)
                                ), # shape = [None, rnn_output_dim, 1]
                            2) # shape = [None, rnn_output_dim]

        self.logits = keras.layers.Dense(label_num, use_bias=True)(outputs)
        self.probability = tf.nn.softmax(self.logits, name='probability')

        self.cost = tf.nn.sparse_softmax_cross_entropy_with_logits(
                                                                    labels = self.Y, 
                                                                    logits = self.logits)
        self.cost = tf.reduce_mean(self.cost)
        self.optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(self.cost)
        self.pre_y = tf.argmax(self.logits, 1, name='pre_y')
        correct_pred = tf.equal(self.pre_y, self.Y)
        self.accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
2.5 训练模型
  1. 将预处理好的数据集切分为80%的训练集,10%作为验证集,10%作为测试集
  2. 选定Multi_LSTM, Bi_RNN, Bi_RNN_Attention其中一个模型
  3. 每使用一次训练集进行训练后,就使用验证集进行测试。
  4. 当验证集的准确率连续下降5次,就停止步骤3,然后使用测试集的结果作为模型的最终性能。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/made_in_china_too/article/details/106635755

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签