主頁 >  其他 > 使用CNN和Python實施的肺炎檢測

使用CNN和Python實施的肺炎檢測

2020-10-17 13:52:12 其他

作者|Muhammad Ardi
編譯|Flin
來源|analyticsvidhya

介紹

嘿!幾個小時前我剛剛完成一個深度學習專案,現在我想分享一下我所做的事情,這一挑戰的目標是確定一個人是否患有肺炎,如果是,則確定是否由細菌或病毒引起,好吧,我覺得這個專案應該叫做分類而不是檢測,

換句話說,此任務將是一個多分類問題,其中標簽名稱為:normal(正常),virus(病毒)和bacteria(細菌),為了解決這個問題,我將使用CNN(卷積神經網路),它具有出色的影像分類能力,,不僅如此,在這里我還實作了影像增強技術,以提高模型性能,順便說一句,我獲得了80%的測驗資料準確性,這對我來說是非常令人印象深刻的,

可以從該Kaggle鏈接下載此專案中使用的資料集,

  • https://www.kaggle.com/paultimothymooney/chest-xray-pneumonia

整個資料集本身的大小約為1 GB,因此下載可能需要一段時間,或者,我們也可以直接創建一個Kaggle Notebook并在那里編碼整個專案,因此我們甚至不需要下載任何內容,接下來,如果瀏覽資料集檔案夾,你將看到有3個子檔案夾,即train,test和val,

好吧,我認為這些檔案夾名稱是不言自明的,此外,train檔案夾中的資料分別包括正常,病毒和細菌類別的1341、1345和2530個樣本,我想這就是我介紹的全部內容了,現在讓我們進入代碼的撰寫!

注意:我在本文結尾處放置了該專案中使用的全部代碼,

加載模塊和訓練影像

使用計算機視覺專案時,要做的第一件事是加載所有必需的模塊和影像資料本身,我使用tqdm模塊顯示進度條,稍后你將看到它有用的原因,

我最后匯入的是來自Keras模塊的ImageDataGenerator,該模塊將幫助我們在訓練程序中實施影像增強技術,

import os
import cv2
import pickle
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from tqdm import tqdm
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import confusion_matrix
from keras.models import Model, load_model
from keras.layers import Dense, Input, Conv2D, MaxPool2D, Flatten
from keras.preprocessing.image import ImageDataGeneratornp.random.seed(22)

接下來,我定義兩個函式以從每個檔案夾加載影像資料,乍一看,下面的兩個功能可能看起來完全一樣,但是在使用粗體顯示的行上實際上存在一些差異,這樣做是因為NORMAL和PNEUMONIA檔案夾中的檔案名結構略有不同,盡管有所不同,但兩個功能執行的其他程序基本相同,

首先,將所有影像調整為200 x 200像素,

這一點很重要,因為所有檔案夾中的影像都有不同的尺寸,而神經網路只能接受具有固定陣列大小的資料,

接下來,基本上所有影像都存盤有3個顏色通道,這對X射線影像來說是多余的,因此,我的想法是將這些彩色影像都轉換為灰度影像,

# Do not forget to include the last slash
def load_normal(norm_path):
    norm_files = np.array(os.listdir(norm_path))
    norm_labels = np.array(['normal']*len(norm_files))
    
    norm_images = []
    for image in tqdm(norm_files):
        image = cv2.imread(norm_path + image)
        image = cv2.resize(image, dsize=(200,200))
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        norm_images.append(image)
        
    norm_images = np.array(norm_images)
    
    return norm_images, norm_labels
def load_pneumonia(pneu_path):
    pneu_files = np.array(os.listdir(pneu_path))
    pneu_labels = np.array([pneu_file.split('_')[1] for pneu_file in pneu_files])
    
    pneu_images = []
    for image in tqdm(pneu_files):
        image = cv2.imread(pneu_path + image)
        image = cv2.resize(image, dsize=(200,200))
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        pneu_images.append(image)
        
    pneu_images = np.array(pneu_images)
    
    return pneu_images, pneu_labels

宣告了以上兩個函式后,現在我們可以使用它來加載訓練資料了,如果你運行下面的代碼,你還將看到為什么我選擇在該專案中實作tqdm模塊,

norm_images, norm_labels = load_normal('/kaggle/input/chest-xray-pneumonia/chest_xray/train/NORMAL/')pneu_images, pneu_labels = load_pneumonia('/kaggle/input/chest-xray-pneumonia/chest_xray/train/PNEUMONIA/')

到目前為止,我們已經獲得了幾個陣列:norm_images,norm_labels,pneu_images和pneu_labels,

帶_images后綴的表示它包含預處理的影像,而帶_labels后綴的陣串列示它存盤了所有基本資訊(也稱為標簽),換句話說,norm_images和pneu_images都將成為我們的X資料,其余的將成為y資料,

為了使專案看起來更簡單,我將這些陣列的值連接起來并存盤在X_train和y_train陣列中,

X_train = np.append(norm_images, pneu_images, axis=0)
y_train = np.append(norm_labels, pneu_labels)

順便說一句,我使用以下代碼獲取每個類的影像數:

顯示多張影像

好吧,在這個階段,顯示幾個影像并不是強制性的,但我想做是為了確保圖片是否已經加載和預處理好,下面的代碼用于顯示14張從X_train陣列隨機拍攝的影像以及標簽,

fig, axes = plt.subplots(ncols=7, nrows=2, figsize=(16, 4))

indices = np.random.choice(len(X_train), 14)
counter = 0

for i in range(2):
    for j in range(7):
        axes[i,j].set_title(y_train[indices[counter]])
        axes[i,j].imshow(X_train[indices[counter]], cmap='gray')
        axes[i,j].get_xaxis().set_visible(False)
        axes[i,j].get_yaxis().set_visible(False)
        counter += 1
plt.show()

我們可以看到上圖,所有影像現在都具有完全相同的大小,這與我用于本帖子封面圖片的影像不同,

加載測驗影像

我們已經知道所有訓練資料都已成功加載,現在我們可以使用完全相同的函式加載測驗資料,步驟幾乎相同,但是這里我將那些加載的資料存盤在X_test和y_test陣列中,用于測驗的資料本身包含624個樣本,

norm_images_test, norm_labels_test = load_normal('/kaggle/input/chest-xray-pneumonia/chest_xray/test/NORMAL/')pneu_images_test, pneu_labels_test = load_pneumonia('/kaggle/input/chest-xray-pneumonia/chest_xray/test/PNEUMONIA/')X_test = np.append(norm_images_test, pneu_images_test, axis=0)
y_test = np.append(norm_labels_test, pneu_labels_test)

此外,我注意到僅加載整個資料集就需要很長時間,因此,我將使用pickle模塊將X_train,X_test,y_train和y_test保存在單獨的檔案中,這樣我下次想再使用這些資料的時候,就不需要再次運行這些代碼了,

# Use this to save variables
with open('pneumonia_data.pickle', 'wb') as f:
    pickle.dump((X_train, X_test, y_train, y_test), f)# Use this to load variables
with open('pneumonia_data.pickle', 'rb') as f:
    (X_train, X_test, y_train, y_test) = pickle.load(f)

由于所有X資料都經過了很好的預處理,因此現在使用標簽y_train和y_test了,

標簽預處理

此時,兩個y變數都由以字串資料型別撰寫的正常,細菌或病毒組成,實際上,這樣的標簽只是神經網路所不能接受的,因此,我們需要將其轉換為單一格式,

幸運的是,我們從Scikit-Learn模塊獲取了 OneHotEncoder物件,它對完成轉換非常有幫助,為此,我們需要先在y_train和y_test上創建一個新軸,(我們創建了這個新軸,因為那是OneHotEncoder期望的形狀),

y_train = y_train[:, np.newaxis]
y_test = y_test[:, np.newaxis]

接下來,像這樣初始化one_hot_encoder,請注意,在這里我將False作為稀疏引數傳遞,以便簡化下一步,但是,如果你想使用稀疏矩陣,則只需使用sparse = True或將引數保留為空即可,

one_hot_encoder = OneHotEncoder(sparse=False)

最后,我們將使用one_hot_encoder將這些y資料轉換為one-hot,然后將編碼后的標簽存盤在y_train_one_hot和y_test_one_hot中,這兩個陣列是我們將用于訓練的標簽,

y_train_one_hot = one_hot_encoder.fit_transform(y_train)
y_test_one_hot = one_hot_encoder.transform(y_test)

將資料X重塑為(None,200,200,1)

現在讓我們回到X_train和X_test,重要的是要知道這兩個陣列的形狀分別為(5216、200、200)和(624、200、200),

乍一看,這兩個形狀看起來還可以,因為我們可以使用plt.imshow()函式進行顯示,但是,這種形狀卷積層不可接受,因為它希望將一個顏色通道作為其輸入,

因此,由于該影像本質上是灰度影像,因此我們需要添加一個1維的新軸,該軸將被卷積層識別為唯一的顏色通道,雖然它的實作并不像我的解釋那么復雜:

X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], X_test.shape[2], 1)

運行上述代碼后,如果我們同時檢查X_train和X_test的形狀,那么我們將看到現在的形狀分別是(5216,200,200,1)和(624,200,200,1),

資料擴充

增加資料(或者更具體地說是增加訓練資料)的要點是,我們將通過創建更多的樣本(每個樣本都具有某種隨機性)來增加用于訓練的資料數量,這些隨機性可能包括平移、旋轉、縮放、剪切和翻轉,

這種技術可以幫助我們的神經網路分類器減少過擬合,或者說,它可以使模型更好地泛化資料樣本,幸運的是,由于存在可以從Keras模塊匯入的ImageDataGenerator物件,實作非常簡單,

datagen = ImageDataGenerator(
        rotation_range = 10,  
        zoom_range = 0.1, 
        width_shift_range = 0.1, 
        height_shift_range = 0.1)

因此,我在上面的代碼中所做的基本上是設定隨機范圍,如果你想了解每個引數的詳細資訊,請點擊這里鏈接到ImageDataGenerator的檔案,

  • https://keras.io/api/preprocessing/image/

接下來,在初始化datagen物件之后,我們需要做的是使它和我們的X_train相匹配,然后,該程序被隨后施加的flow()的方法,該步驟中是非常有用的,使得所述 train_gen物件現在能夠產生增強資料的批次,

datagen.fit(X_train)train_gen = datagen.flow(X_train, y_train_one_hot, batch_size=32)

CNN(卷積神經網路)

現在是時候真正構建神經網路架構了,讓我們從輸入層(input1)開始,因此,這一層基本上會獲取X資料中的所有影像樣本,因此,我們需要確保第一層接受與影像尺寸完全相同的形狀,值得注意的是,我們僅需要定義(寬度,高度,通道),而不是(樣本,寬度,高度,通道),

此后,此輸入層連接到幾對卷積池層對,然后最終連接到全連接層,請注意,由于ReLU的計算速度比S型更快,因此模型中的所有隱藏層都使用ReLU激活函式,因此所需的訓練時間更短,最后,要連接的最后一層是output1,它由3個具有softmax激活函式的神經元組成,

這里使用softmax是因為我們希望輸出是每個類別的概率值,

input1 = Input(shape=(X_train.shape[1], X_train.shape[2], 1))

cnn = Conv2D(16, (3, 3), activation='relu', strides=(1, 1), 
    padding='same')(input1)
cnn = Conv2D(32, (3, 3), activation='relu', strides=(1, 1), 
    padding='same')(cnn)
cnn = MaxPool2D((2, 2))(cnn)

cnn = Conv2D(16, (2, 2), activation='relu', strides=(1, 1), 
    padding='same')(cnn)
cnn = Conv2D(32, (2, 2), activation='relu', strides=(1, 1), 
    padding='same')(cnn)
cnn = MaxPool2D((2, 2))(cnn)

cnn = Flatten()(cnn)
cnn = Dense(100, activation='relu')(cnn)
cnn = Dense(50, activation='relu')(cnn)
output1 = Dense(3, activation='softmax')(cnn)

model = Model(inputs=input1, outputs=output1)

在使用上面的代碼構造了神經網路之后,我們可以通過對model物件應用summary()來顯示模型的摘要,下面是我們的CNN模型的詳細情況,我們可以看到我們總共有800萬個引數——這確實很多,好吧,這就是為什么我在Kaggle Notebook上運行這個代碼,

總之,在構建模型之后,我們需要使用分類交叉熵損失函式和Adam優化器來編譯神經網路,使用這個損失函式,因為它只是多類分類任務中常用的函式,同時,我選擇Adam作為優化器,因為它是在大多數神經網路任務中最小化損失的最佳選擇,

model.compile(loss='categorical_crossentropy', 
              optimizer='adam', metrics=['acc'])

現在是時候訓練模型了!在這里,我們將使用fit_generator()而不是fit(),因為我們將從train_gen物件獲取訓練資料,如果你關注資料擴充部分,你會注意到train_gen是使用X_train和y_train_one_hot創建的,因此,我們不需要在fit_generator()方法中顯式定義X-y對,

history = model.fit_generator(train_gen, epochs=30, 
          validation_data=https://www.cnblogs.com/panchuangai/p/(X_test, y_test_one_hot))

train_gen的特殊之處在于,訓練程序中將使用具有一定隨機性的樣本來完成,因此,我們在X_train中擁有的所有訓練資料都不會直接輸入到神經網路中,取而代之的是,這些樣本將被用作生成器的基礎,通過一些隨機變換生成一個新影像,

此外,該生成器在每個時期產生不同的影像,這對于我們的神經網路分類器更好地泛化測驗集中的樣本非常有利,下面是訓練的程序,

Epoch 1/30
163/163 [==============================] - 19s 114ms/step - loss: 5.7014 - acc: 0.6133 - val_loss: 0.7971 - val_acc: 0.7228
.
.
.
Epoch 10/30
163/163 [==============================] - 18s 111ms/step - loss: 0.5575 - acc: 0.7650 - val_loss: 0.8788 - val_acc: 0.7308
.
.
.
Epoch 20/30
163/163 [==============================] - 17s 102ms/step - loss: 0.5267 - acc: 0.7784 - val_loss: 0.6668 - val_acc: 0.7917
.
.
.
Epoch 30/30
163/163 [==============================] - 17s 104ms/step - loss: 0.4915 - acc: 0.7922 - val_loss: 0.7079 - val_acc: 0.8045

整個訓練本身在我的Kaggle Notebook上花費了大約10分鐘,所以要耐心點!經過訓練后,我們可以繪制出準確度得分的提高和損失值的降低,如下所示:

plt.figure(figsize=(8,6))
plt.title('Accuracy scores')
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.legend(['acc', 'val_acc'])
plt.show()plt.figure(figsize=(8,6))
plt.title('Loss value')
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.legend(['loss', 'val_loss'])
plt.show()

根據上面的兩個圖,我們可以說,即使在這30個時期內測驗準確性和損失值都在波動,模型的性能仍在不斷提高,

這里要注意的另一重要事情是,由于我們在專案的早期應用了資料增強方法,因此該模型不會遭受過擬合的困擾,我們在這里可以看到,在最終迭代中,訓練和測驗資料的準確性分別為79%和80%,

有趣的事實:在實施資料增強方法之前,我在訓練資料上獲得了100%的準確性,在測驗資料上獲得了64%的準確性,這顯然是過擬合了,因此,我們可以在此處清楚地看到,增加訓練資料對于提高測驗準確性得分非常有效,同時也可以減少過擬合,

模型評估

現在,讓我們深入了解使用混淆矩陣得出的測驗資料的準確性,首先,我們需要預測所有X_test并將結果從獨熱格式轉換回其實際的分類標簽,

predictions = model.predict(X_test)
predictions = one_hot_encoder.inverse_transform(predictions)

接下來,我們可以像這樣使用confusion_matrix()函式:

cm = confusion_matrix(y_test, predictions)

重要的是要注意函式中使用的引數是(實際值,預測值),該混淆矩陣函式的回傳值是一個二維陣列,用于存盤預測分布,為了使矩陣更易于解釋,我們可以使用Seaborn模塊中的heatmap()函式進行顯示,順便說一句,這里的類名串列的值是根據one_hot_encoder.categories_回傳的順序獲取的,

classnames = ['bacteria', 'normal', 'virus']plt.figure(figsize=(8,8))
plt.title('Confusion matrix')
sns.heatmap(cm, cbar=False, xticklabels=classnames, yticklabels=classnames, fmt='d', annot=True, cmap=plt.cm.Blues)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.show()

根據上面的混淆矩陣,我們可以看到45張病毒X射線影像被預測為細菌,這可能是因為很難區分這兩種肺炎,但是,至少因為我們對242個樣本中的232個進行了正確分類,所以我們的模型至少能夠很好地預測由細菌引起的肺炎,

這就是整個專案!謝謝閱讀!下面是運行整個專案所需的所有代碼,

import os
import cv2
import pickle	# Used to save variables
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from tqdm import tqdm	# Used to display progress bar
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import confusion_matrix
from keras.models import Model, load_model
from keras.layers import Dense, Input, Conv2D, MaxPool2D, Flatten
from keras.preprocessing.image import ImageDataGenerator	# Used to generate images

np.random.seed(22)

# Do not forget to include the last slash
def load_normal(norm_path):
    norm_files = np.array(os.listdir(norm_path))
    norm_labels = np.array(['normal']*len(norm_files))
    
    norm_images = []
    for image in tqdm(norm_files):
		# Read image
        image = cv2.imread(norm_path + image)
		# Resize image to 200x200 px
        image = cv2.resize(image, dsize=(200,200))
		# Convert to grayscale
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        norm_images.append(image)
        
    norm_images = np.array(norm_images)
    
    return norm_images, norm_labels

def load_pneumonia(pneu_path):
    pneu_files = np.array(os.listdir(pneu_path))
    pneu_labels = np.array([pneu_file.split('_')[1] for pneu_file in pneu_files])
    
    pneu_images = []
    for image in tqdm(pneu_files):
		# Read image
        image = cv2.imread(pneu_path + image)
		# Resize image to 200x200 px
        image = cv2.resize(image, dsize=(200,200))
		# Convert to grayscale
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        pneu_images.append(image)
        
    pneu_images = np.array(pneu_images)
    
    return pneu_images, pneu_labels


print('Loading images')
# All images are stored in _images, all labels are in _labels
norm_images, norm_labels = load_normal('/kaggle/input/chest-xray-pneumonia/chest_xray/train/NORMAL/')
pneu_images, pneu_labels = load_pneumonia('/kaggle/input/chest-xray-pneumonia/chest_xray/train/PNEUMONIA/')

# Put all train images to X_train 
X_train = np.append(norm_images, pneu_images, axis=0)

# Put all train labels to y_train
y_train = np.append(norm_labels, pneu_labels)

print(X_train.shape)
print(y_train.shape)
# Finding out the number of samples of each class
print(np.unique(y_train, return_counts=True))

print('Display several images')
fig, axes = plt.subplots(ncols=7, nrows=2, figsize=(16, 4))

indices = np.random.choice(len(X_train), 14)
counter = 0

for i in range(2):
    for j in range(7):
        axes[i,j].set_title(y_train[indices[counter]])
        axes[i,j].imshow(X_train[indices[counter]], cmap='gray')
        axes[i,j].get_xaxis().set_visible(False)
        axes[i,j].get_yaxis().set_visible(False)
        counter += 1
plt.show()


print('Loading test images')
# Do the exact same thing as what we have done on train data
norm_images_test, norm_labels_test = load_normal('/kaggle/input/chest-xray-pneumonia/chest_xray/test/NORMAL/')
pneu_images_test, pneu_labels_test = load_pneumonia('/kaggle/input/chest-xray-pneumonia/chest_xray/test/PNEUMONIA/')
X_test = np.append(norm_images_test, pneu_images_test, axis=0)
y_test = np.append(norm_labels_test, pneu_labels_test)

# Save the loaded images to pickle file for future use
with open('pneumonia_data.pickle', 'wb') as f:
    pickle.dump((X_train, X_test, y_train, y_test), f)

# Here's how to load it
with open('pneumonia_data.pickle', 'rb') as f:
    (X_train, X_test, y_train, y_test) = pickle.load(f)

print('Label preprocessing')

# Create new axis on all y data
y_train = y_train[:, np.newaxis]
y_test = y_test[:, np.newaxis]

# Initialize OneHotEncoder object
one_hot_encoder = OneHotEncoder(sparse=False)

# Convert all labels to one-hot
y_train_one_hot = one_hot_encoder.fit_transform(y_train)
y_test_one_hot = one_hot_encoder.transform(y_test)

print('Reshaping X data')
# Reshape the data into (no of samples, height, width, 1), where 1 represents a single color channel
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], X_test.shape[2], 1)

print('Data augmentation')
# Generate new images with some randomness
datagen = ImageDataGenerator(
		rotation_range = 10,  
        zoom_range = 0.1, 
        width_shift_range = 0.1, 
        height_shift_range = 0.1)

datagen.fit(X_train)
train_gen = datagen.flow(X_train, y_train_one_hot, batch_size = 32)

print('CNN')

# Define the input shape of the neural network
input_shape = (X_train.shape[1], X_train.shape[2], 1)
print(input_shape)

input1 = Input(shape=input_shape)

cnn = Conv2D(16, (3, 3), activation='relu', strides=(1, 1), 
    padding='same')(input1)
cnn = Conv2D(32, (3, 3), activation='relu', strides=(1, 1), 
    padding='same')(cnn)
cnn = MaxPool2D((2, 2))(cnn)

cnn = Conv2D(16, (2, 2), activation='relu', strides=(1, 1), 
    padding='same')(cnn)
cnn = Conv2D(32, (2, 2), activation='relu', strides=(1, 1), 
    padding='same')(cnn)
cnn = MaxPool2D((2, 2))(cnn)

cnn = Flatten()(cnn)
cnn = Dense(100, activation='relu')(cnn)
cnn = Dense(50, activation='relu')(cnn)
output1 = Dense(3, activation='softmax')(cnn)

model = Model(inputs=input1, outputs=output1)

model.compile(loss='categorical_crossentropy', 
              optimizer='adam', metrics=['acc'])

# Using fit_generator() instead of fit() because we are going to use data
# taken from the generator. Note that the randomness is changing
# on each epoch
history = model.fit_generator(train_gen, epochs=30, 
          validation_data=https://www.cnblogs.com/panchuangai/p/(X_test, y_test_one_hot))

# Saving model
model.save('pneumonia_cnn.h5')

print('Displaying accuracy')
plt.figure(figsize=(8,6))
plt.title('Accuracy scores')
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.legend(['acc', 'val_acc'])
plt.show()

print('Displaying loss')
plt.figure(figsize=(8,6))
plt.title('Loss value')
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.legend(['loss', 'val_loss'])
plt.show()

# Predicting test data
predictions = model.predict(X_test)
print(predictions)

predictions = one_hot_encoder.inverse_transform(predictions)

print('Model evaluation')
print(one_hot_encoder.categories_)

classnames = ['bacteria', 'normal', 'virus']

# Display confusion matrix
cm = confusion_matrix(y_test, predictions)
plt.figure(figsize=(8,8))
plt.title('Confusion matrix')
sns.heatmap(cm, cbar=False, xticklabels=classnames, yticklabels=classnames, fmt='d', annot=True, cmap=plt.cm.Blues)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.show()

參考文獻

J?drzejDudzicz對胸部X線檢查的肺炎檢出率約為92%

  • https://www.kaggle.com/jedrzejdudzicz/pneumonia-detection-on-chest-x-ray-accuracy-92

Kerian ImageDataGenerator和Adrian Rosebrock的資料增強

  • https://www.pyimagesearch.com/2019/07/08/keras-imagedatagenerator-and-data-augmentation/

原文鏈接:https://www.analyticsvidhya.com/blog/2020/09/pneumonia-detection-using-cnn-with-implementation-in-python/

歡迎關注磐創AI博客站:
http://panchuang.net/

sklearn機器學習中文官方檔案:
http://sklearn123.com/

歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/

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

標籤:其他

上一篇:kiCAD 從原理圖到PCB封裝

下一篇:kiCAD ERC檢查 引腳 XX 元件 未被驅動 增加PWR_FLAG

標籤雲
其他(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