主頁 >  其他 > numpy 構建深度神經網路來識別圖片中是否有貓

numpy 構建深度神經網路來識別圖片中是否有貓

2020-09-17 12:26:50 其他

搭建簡單神經網路來識別圖片中是否有貓
代碼借鑒地址:純用NumPy實作神經網路

搭建一個簡單易懂的神經網路來幫你理解深度神經網路
通過簡單的貓識別的例子來幫你進一步進行理解
本代碼用 numpy 來實作,不含有正則化,批量等演算法

這里我們先來理清楚神經網路的步驟

(1) 構建資料,我們要構建出這樣的一個資料,shape = (n, m),n 代表特征數,m 代表樣本數
(2) 初始化引數,使用隨機初始化引數 W 和 b
(3) 前向傳播,
(4) 計算損失,
(5) 反向傳播,
(6) 更新引數,
(7) 構建模型,
(8) 預測,預測其實就是重新進行一次前向傳播

清楚了這些步驟之后,我們在構建神經網路的時候就不至于無從下手了
接下來我們就根據上面理出來的步驟開始一步一步來構架深度神經網路吧


目錄
目錄

  • 1 構建資料
  • 2 隨機初始化資料
  • 3 前向傳播
  • 4 計算損失
  • 5 反向傳播
  • 6 更新引數
  • 7 構建模型
  • 8 預測
  • 9 開始訓練
  • 10 進行預測
  • 11 以圖片的形式展示預測后的結果

1 構建資料

我們先來看一下資料集是怎樣的

我們從 h5 檔案中來獲取我們需要的資料
這里,我準備了兩個檔案,一個是 test_catvnoncat.h5,另外一個是 test_catvnoncat.h5,第一個檔案里面放置的是訓練集,第二個檔案放置的是測驗集

# 從檔案加載資料的函式
def load_data():
    # 把檔案讀取到記憶體中
    train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")
    train_x_orig = np.array(train_dataset["train_set_x"][:]) # 獲取訓練集特征
    train_y_orig = np.array(train_dataset["train_set_y"][:]) # 獲取訓練標簽

    test_dataset = h5py.File('datasets/test_catvnoncat.h5', "r")
    test_x_orig = np.array(test_dataset["test_set_x"][:]) # 獲取測驗集特征
    test_y_orig = np.array(test_dataset["test_set_y"][:]) # 獲取測驗標簽

    classes = np.array(test_dataset["list_classes"][:]) # 類別,即 1 和 0
    
    # 現在的資料維度是 (m,),我們要把它變成 (1, m),m 代表樣本數量
    train_y_orig = train_y_orig.reshape((1, train_y_orig.shape[0]))
    test_y_orig = test_y_orig.reshape((1, test_y_orig.shape[0]))
    
    return train_x_orig, train_y_orig, test_x_orig, test_y_orig, classes

我們可以輸出這些圖片看看


from random import randint
import matplotlib.pyplot as plt

# 加載資料
train_x_orig, train_y, test_x_orig, test_y, classes = load_data()

# 隨機從訓練集中選取一張圖片
index = randint(0, 209)
img = train_x_orig[index]

# 顯示這張圖片
plt.imshow(img)

print ('它的標簽是:{}'.format(train_y[0][index]))

演示結果為:

轉換資料

因為我們的資料為是標準的圖片資料,我們要把它轉換成符合我們輸入的格式
也就是 (n, m) 格式,n 代表特征數,m 代表樣本數量


train_x_orig, train_y, test_x_orig, test_y, classes = load_data()

m_train = train_x_orig.shape[0] # 訓練樣本的數量
m_test = test_x_orig.shape[0] # 測驗樣本的數量
num_px = test_x_orig.shape[1] # 每張圖片的寬/高

# 為了方便后面進行矩陣運算,我們需要將樣本資料進行扁平化和轉置
# 處理后的陣列各維度的含義是(圖片資料,樣本數)
train_x_flatten = train_x_orig.reshape(train_x_orig.shape[0], -1).T
test_x_flatten = test_x_orig.reshape(test_x_orig.shape[0], -1).T 

# 下面我們對特征資料進行了簡單的標準化處理(除以255,使所有值都在[0,1]范圍內)
train_x = train_x_flatten/255.
test_x = test_x_flatten/255.

最后輸出資料是 (12288, m) 維度的,12288 代表特征,即 64*64*3=12288

2 隨機初始化資料

定義神經網路的結構
在初始化之前我們要明白我們要搭建的這樣一個網路的結構是如何的,這里我們采取下面的方式來定義網路的結構


# 定義神經網路的結構
'''
即有四層,第一層為 12288 的特征輸入,第二層有 20 個單元,以此類推
'''
nn_architecture = [
    {'input_dim': 12288, 'output_dim': 20, 'activation': 'relu'},
    {'input_dim': 20, 'output_dim': 7, 'activation': 'relu'},
    {'input_dim': 7, 'output_dim': 5, 'activation': 'relu'},
    {'input_dim': 5, 'output_dim': 1, 'activation': 'sigmoid'}
]

初始化


# 根據結構隨機初始化引數 W, b
def init_params(nn_architecture):
    
    np.random.seed(1)
    
    # 用來存放產生的引數
    params = {}

    for id, layer in enumerate(nn_architecture):
        # layer_id -> [1, 2, 3, 4]
        layer_id = id + 1
        params['W' + str(layer_id)] = np.random.randn(layer['output_dim'], layer['input_dim']) / np.sqrt(layer['input_dim'])
        params['b' + str(layer_id)] = np.zeros((layer['output_dim'], 1))
    
    return params

3 前向傳播

先來看看前向傳播做了些什么事情

激活函式


def sigmoid(Z):
    '''
    引數
    Z: shape = (output_dim, m) # output_dim 指當前層的單元數
    
    回傳值
    1/(1+np.exp(-Z)): sigmoid 計算結果 shape = (output_dim, m)
    '''
    return 1/(1+np.exp(-Z))

def relu(Z):
    '''
    引數
    Z: shape = (output_dim, m) # output_dim 指當前層的單元數
    
    回傳值
    np.maximum(0, Z): relu 計算結果 shape = (output_dim, m)
    '''

    return np.maximum(0,Z)

構建單層前向傳播
也就是我們在一層內做了些什么,我們用這個函式來實作它

$$Z_curr = W_curr·A_prev + b_curr$$
$$A_curr = g(Z_curr)$$


# 單層前向傳播
def layer_forward(W_curr, b_curr, A_prev, activation):
    '''
    計算
    Z_curr = W_curr·A_prev + b_curr
    A_curr = g(Z_curr)
    
    引數
    W_curr: 當前層的 W 引數
    b_curr: 當前層的 b 引數
    A_prev: 上一層的 A 矩陣
    activation: 當前層要用的激活函式
    
    回傳值
    Z_curr: 當前層的 Z
    A_curr: 當前層的 A
    '''

    Z_curr = np.dot(W_curr, A_prev) + b_curr
    
    # 判斷激活函式并求 A
    if activation == 'relu':
        A_curr = relu(Z_curr)
    elif activation == 'sigmoid':
        A_curr = sigmoid(Z_curr)
    else:
        raise Exception('不支持的激活函式型別!')
    
    return Z_curr, A_curr

構建完整的前向傳播
完整的前向傳播網路中,我把 Z_curr 和 A_prev 封裝成一個字典放入當前層的快取中,以便后面進行梯度下降的時候用到,然后再把所有層的快取構成一個串列 caches,這個 caches 我們在后面要用到,所以這里我們要回傳兩個資料 A 和 caches


# 完整前向傳播
def full_forward(X, params, nn_architecture):
    '''
    引數
    X: 輸入
    params: W, b 引數存放的變數
    nn_architecture: 結構
    
    caches 存盤格式
    因為反向傳播的時候也要用到上一層的 A,
    所以這里把上一層的 A,當前層的 Z 存入到 caches 中,方便呼叫
    caches = [
    {'A_prev': A_prev, 'Z_curr': Z_curr}, # 第一層存盤的資料
    {'A_prev': A_prev, 'Z_curr': Z_curr}, 
    ...
    ...
    ]
    
    回傳值
    A_curr: 最后一層的 A ,也就是 AL(Y_hat)
    caches: 存放上一層的 A 和 當前層的 Z 的串列
    '''
    caches = []
    
    # X 作為第零層 A
    A_curr = X
    
    for id, layer in enumerate(nn_architecture):
        # layer_id -> [1, 2, 3, 4]
        layer_id = id + 1
        
        # 獲取上一層的 A
        A_prev = A_curr
        
        # 從 params 中獲取當前層的 W 和 b
        W_curr = params['W' + str(layer_id)]
        b_curr = params['b' + str(layer_id)]
        # 從 layer 中獲取激活函式
        activation = layer['activation']
        
        # 求當前層的 Z 和 A
        Z_curr, A_curr = layer_forward(W_curr, b_curr, A_prev, activation)
        
        # 把 上一層的 A 和 當前層的 Z 放入記憶體
        caches.append({
            'A_prev': A_prev,
            'Z_curr': Z_curr
        })
    return A_curr, caches

4 計算損失

計算損失的公式
$$J(cost) = -\frac{1}{m} [Y·log(Y_hat).T + (1-Y)·log(1-Y_hat).T]$$


# 獲取損失值
def get_cost(Y_hat, Y):
    # 獲取樣本數量
    m = Y_hat.shape[1]
    
    cost = -1 / m * (np.dot(Y, np.log(Y_hat).T) + np.dot(1 - Y, np.log(1 - Y_hat).T))
    
    # cost 為一個一行一列的資料[[0.256654]], np.squeeze 讓其變成一個數值
    cost = np.squeeze(cost)
    
    return cost

這里我們還可以定義一個函式來求準確度


# 把預測值進行分類,預測值求出來都是一些小數,對于二分類問題,我們把對他分成兩類
def convert_into_class(Y_hat):
    # 復制矩陣
    prob = np.copy(Y_hat)
    # 把矩陣里面所有的 >0.5 歸類為 1
    #                  <=0.5 歸類為 0
    prob[prob > 0.5] = 1
    prob[prob <= 0.5] = 0
    
    return prob

# 獲取準確度
def get_accuracy(Y_hat, Y):
    # 先進行分類,再求精度
    prob = convert_into_class(Y_hat)
#     accu = float(np.dot(Y, prob.T) + np.dot(1 - Y, 1 - prob.T)) / float(Y_hat.shape[1])
    # 上面的注釋的方法也可求精確度
    '''
    這里我們的原理是,把預測值和真實值進行比較,相同的,
    就代表預測正確,就把他們的個數加起來,然后再除總的
    樣本量,Y_hat.shape[1] 就代表總的樣本量
    '''
    accu = np.sum((prob == Y) / Y_hat.shape[1])
    accu = np.squeeze(accu)
    
    return accu

5 反向傳播

還是一樣我們先來看看反向傳播的結構

主要步驟就是,我們先通過 J(cost) 求出對 A4 的偏導 dA4,再進行單層的反向傳播, L 代表最后層,l 代表當前層
$$dA^{L} = -(\frac{Y}{Y_hat} - \frac{1-Y}{1-Y_hat})$$

對激活函式進行求導


'''
計算dZ
dZ = dA * g(Z) * (1 - g(Z))
'''
def relu_backward(dA, cache):  
    '''
    dA: shape = (output_dim, m) # output_dim 為當前層的單元數
    cache: shape = (output_dim, m)
    '''
    Z = cache
    dZ = np.array(dA, copy=True) # 復制矩陣
    
    # When z <= 0, dZ = 0
    dZ[Z <= 0] = 0
        
    return dZ

def sigmoid_backward(dA, cache):
    '''
    dA: shape = (output_dim, m) # output_dim 指當前層的單元數
    cache: shape = (output_dim, m)
    '''
    Z = cache
    
    s = 1/(1+np.exp(-Z))
    dZ = dA * s * (1-s)
    
    assert (dZ.shape == Z.shape)
    
    return dZ

構建單層反向傳播
在單層里面我們主要就是計算 dZ, dW, db

$$dZ^{[l]} = dA{[l]}*g{[l]'}(Z^{[l]})$$
$$dW^{[l]} = dZ{[l]}·A{[l-1]}.T$$
$$db^{[l]} = sum(dZ^{[l]})$$


# 單層反向傳播
def layer_backward(dA_curr, W_curr, Z_curr, A_prev, activation):
    '''
    計算
    dZ = dA * g(Z) * (1 - g(Z))
    dW = dZ·A.T / m
    db = np.sum(dZ, axis=1, keepdims=True) / m
    
    引數
    dA_curr: 當前層的 dA
    W_curr: 當前層的 W 引數
    Z_curr: 當前層的 Z 引數
    A_prev: 上一層的 A 引數
    activation: 當前層的激活函式
    
    回傳值
    dW_curr: 當前層的 dW
    db_curr: 當前層的 db
    dA_prev: 上一層的 dA
    '''
    m = A_prev.shape[1] # 求出樣本個數
    # 求出 dZ_curr
    if activation == 'relu':
        dZ_curr = relu_backward(dA_curr, Z_curr)
    elif activation == 'sigmoid':
        dZ_curr = sigmoid_backward(dA_curr, Z_curr)
    else:
        raise Exception ("不支持的激活函式型別!")
        
    # 分別求 dZ, dW, db
    dW_curr = np.dot(dZ_curr, A_prev.T) / m
    db_curr = np.sum(dZ_curr, axis=1, keepdims=True) / m
    dA_prev = np.dot(W_curr.T, dZ_curr)
    
    return dW_curr, db_curr, dA_prev

構建完整的反向傳播
在構建完整的反向傳播的時候,一定要認真核對每一個矩陣的維度
最后回傳的是存放梯度值的字典 grads


# 完整反向傳播
def full_backward(Y_hat, Y, params, caches, nn_architecture):
    '''
    引數
    Y_hat: 預測值(最后一層的 A 值)
    Y: 真實 Y 矩陣
    params: 存放每層 W, b 引數
    caches: 存放有前向傳播中的 A , Z 
    nn_architecture: 結構
    
    回傳
    grads: 梯度值
    '''
    # 存放要進行梯度下降的 dW, db 引數,存放形式和 params 一樣
    grads = {}
    
    # 計算最后一層的 dA
    dA_prev = - (np.divide(Y, Y_hat) - np.divide(1 - Y, 1 - Y_hat))
    
    for id, layer in reversed(list(enumerate(nn_architecture))):
        # layer_id -> [4, 3, 2, 1]
        layer_id = id + 1
        
        # 當前層的 dA 為上一次計算出來的 dA_prev
        dA_curr = dA_prev
        # 從 params 中取出 當前層的 W 引數
        W_curr = params['W' + str(layer_id)]
        # 從 caches 記憶體中取出我們在前向傳播中存放的資料
        A_prev = caches[id]['A_prev']
        Z_curr = caches[id]['Z_curr']
        # 從當前層的結構中取出激活函式
        activation = layer['activation']
        
        # 計算當前層的梯度值 dW, db,以及上一層的 dA
        dW_curr, db_curr, dA_prev = layer_backward(dA_curr,
                                                   W_curr, 
                                                   Z_curr,
                                                   A_prev,
                                                   activation)
        # 把梯度值放入 grads 中
        grads['dW' + str(layer_id)] = dW_curr
        grads['db' + str(layer_id)] = db_curr
    
    return grads

6 更新引數

更新引數的公式

$$W = W - \alpha * dW $$
$$b = b - \alpha * db $$


# 更新引數
def update_params(params, grads, learning_rate):
    '''
    引數
    params: W,b 引數
    grads: 梯度值
    learning_rate: 梯度下降時的學習率
    
    回傳
    params: 更新后的引數
    '''
    for id in range(len(params) // 2):
        # layer_id -> [1, 2, 3, 4]
        layer_id = id + 1
        params['W' + str(layer_id)] -= learning_rate * grads['dW' + str(layer_id)]
        params['b' + str(layer_id)] -= learning_rate * grads['db' + str(layer_id)]
    
    return params

7 構建模型

前面我們把相應的每個步驟的函式都撰寫好了,那么我們現在只需要把他們組合起來即可


# 定義模型
def dnn_model(X, Y, nn_architecture, epochs=3000, learning_rate=0.0075):
    '''
    引數
    X: (n, m)
    Y: (1, m)
    nn_architecture: 網路結構
    epochs: 迭代次數
    learning_rate:學習率

    回傳值
    params: 訓練好的引數
    '''
    np.random.seed(1)
    params = init_params(nn_architecture)
    costs = []
    
    for i in range(1, epochs + 1):
        # 前向傳播
        Y_hat, caches = full_forward(X, params, nn_architecture)
        
        # 計算損失
        cost = get_cost(Y_hat, Y)
        
        # 計算精度
        accu = get_accuracy(Y_hat, Y)
        
        # 反向傳播
        grads = full_backward(Y_hat, Y, params, caches, nn_architecture)
        
        # 更新引數
        params = update_params(params, grads, learning_rate)
        
        if i % 100 == 0:
            print ('Iter: {:05}, cost: {:.5f}, accu: {:.5f}'.format(i, cost, accu))
            costs.append(cost)
            
    # 畫出 cost 曲線圖
    plt.plot(np.squeeze(costs))
    plt.ylabel('cost')
    plt.xlabel('iterations (per tens)')
    plt.title("DNN")
    plt.show()
    
    return params 

8 預測


# 預測函式
def predict(X, Y, params, nn_architecture):
    Y_hat, _ = full_forward(X, params, nn_architecture)
    accu = get_accuracy(Y_hat, Y)
    print ('預測精確度為:{:.2f}'.format(accu))
    return Y_hat

9 開始訓練


# 開始訓練
params = dnn_model(
    train_x, train_y,
    nn_architecture,
)

這是訓練后的結果


Iter: 00100, cost: 0.67239, accu: 0.67943
Iter: 00200, cost: 0.64575, accu: 0.74641
Iter: 00300, cost: 0.62782, accu: 0.72727
Iter: 00400, cost: 0.59732, accu: 0.75598
Iter: 00500, cost: 0.52155, accu: 0.85646
Iter: 00600, cost: 0.48313, accu: 0.87560
Iter: 00700, cost: 0.43010, accu: 0.91866
Iter: 00800, cost: 0.36453, accu: 0.95694
Iter: 00900, cost: 0.34318, accu: 0.93780
Iter: 01000, cost: 0.29341, accu: 0.95215
Iter: 01100, cost: 0.25503, accu: 0.96172
Iter: 01200, cost: 0.22804, accu: 0.97608
Iter: 01300, cost: 0.19706, accu: 0.97608
Iter: 01400, cost: 0.18372, accu: 0.98086
Iter: 01500, cost: 0.16100, accu: 0.98086
Iter: 01600, cost: 0.14842, accu: 0.98086
Iter: 01700, cost: 0.13803, accu: 0.98086
Iter: 01800, cost: 0.12873, accu: 0.98086
Iter: 01900, cost: 0.12087, accu: 0.98086
Iter: 02000, cost: 0.11427, accu: 0.98086
Iter: 02100, cost: 0.10850, accu: 0.98086
Iter: 02200, cost: 0.10243, accu: 0.98086
Iter: 02300, cost: 0.09774, accu: 0.98086
Iter: 02400, cost: 0.09251, accu: 0.98086
Iter: 02500, cost: 0.08844, accu: 0.98565
Iter: 02600, cost: 0.08474, accu: 0.98565
Iter: 02700, cost: 0.08193, accu: 0.98565
Iter: 02800, cost: 0.07815, accu: 0.98565
Iter: 02900, cost: 0.07563, accu: 0.98565
Iter: 03000, cost: 0.07298, accu: 0.99043

10 進行預測


# 預測測驗集的精確度
Y_hat = predict(test_x, test_y, params, nn_architecture)

預測精確度為:0.80

11 以圖片的形式展示預測后的結果


# 顯示圖片
# 因為測驗集有 50 張圖片,所以我們隨機生成 1-50 的整形數字
index = randint(1, 49)
# 因為在前面,我們把資料展開成了 (12288, 50) 的矩陣,現在讓它回歸成圖片的矩陣
img = test_x[:, index].reshape((64, 64, 3))
# 顯示圖片
plt.imshow(img)
# 把預測分類
Y_hat_ = convert_into_class(Y_hat)

# 把 1,0 轉化成漢字并輸出
pred_ = '是' if int(Y_hat_[0, index]) else '不是'
true_ = '是' if int(test_y[0, index]) else '不是'
print ('這張圖片' + true_ + '貓')
print ('預測圖片' + pred_ + '貓')

# 判斷是否預測正確
if int(Y_hat_[0, index]) == int(test_y[0, index]):
    print ('預測正確!')
else:
    print ('預測錯誤!')

這張圖片不是貓
預測圖片不是貓
預測正確!

以上我們就搭建完成了整個實體的代碼搭建,如果你要訓練其他的資料集,那么更改相應的網路結構即可,針對不同的資料集,有不同的結構,比如,我們的 X 有兩個特征,那么第一層的 input_dim 可以改為 2

* 以上代碼為學習時所記錄,如果在文中有錯誤的地方,請聯系我及時修改

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/65604.html

標籤:其他

上一篇:規模、性能、彈性全面升級,讓天下沒有難用的 K8s

下一篇:LeetCode初級演算法--排序和搜索01:第一個錯誤的版本

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more