基于可解释性深度学习的马铃薯叶病害检测

数据集来自kaggle文章,代码较为简单。

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)


# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory


import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

Neural Network Model with TensorFlow and Keras for Classification

import tensorflow as tf
from tensorflow.keras import models,layers
import matplotlib.pyplot as plt


BATCH_SIZE=32
IMAGE_SIZE=224
CHANNELS=3
EPOCHS=50

Loading Image Dataset for Training

dataset=tf.keras.preprocessing.image_dataset_from_directory(
    "/kaggle/input/potato-dataset/PlantVillage",
    shuffle=True,
    image_size=(IMAGE_SIZE,IMAGE_SIZE),
    batch_size=BATCH_SIZE
)

Retrieving Class Names from the Dataset

class_names=dataset.class_names
class_names

Data Visualization

import os


Potato___Early_blight_dir = '/kaggle/input/potato-dataset/PlantVillage/Potato___Early_blight'
Potato___Late_blight_dir = '/kaggle/input/potato-dataset/PlantVillage/Potato___Late_blight'
Potato___healthy_dir = '/kaggle/input/potato-dataset/PlantVillage/Potato___healthy'
import matplotlib.pyplot as plt


# Define the categories and corresponding counts
categories = ['Early Leaf Blight','Late Leaf Blight','Healthy']
counts = [len(os.listdir(Potato___Early_blight_dir)), len(os.listdir(Potato___Late_blight_dir)), len(os.listdir(Potato___healthy_dir))]


# Create a bar plot to visualize the distribution of images
plt.figure(figsize=(12, 6))
plt.bar(categories, counts, color='skyblue')
plt.xlabel('Categories')
plt.ylabel('Number of Images')
plt.title('Distribution of Images in Different Categories')
plt.show()

Visualizing Sample Images from the Dataset

plt.figure(figsize=(10,10))
for image_batch, labels_batch in dataset.take(1):
    print(image_batch.shape)
    print(labels_batch.numpy())
    for i in range(12):
        ax=plt.subplot(3,4,i+1)
        plt.imshow(image_batch[i].numpy().astype("uint8"))
        plt.title(class_names[labels_batch[i]])
        plt.axis("off")

Function to Split Dataset into Training and Validation Set

def get_dataset_partitions_tf(ds, train_split=0.8, val_split=0.2, shuffle=True, shuffle_size=10000):
    assert(train_split+val_split)==1


    ds_size=len(ds)


    if shuffle:
        ds=ds.shuffle(shuffle_size, seed=12)


    train_size=int(train_split*ds_size)
    val_size=int(val_split*ds_size)


    train_ds=ds.take(train_size)
    val_ds=ds.skip(train_size).take(val_size)


    return train_ds, val_ds
train_ds, val_ds =get_dataset_partitions_tf(dataset)

Data Augmentation

train_ds= train_ds.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
val_ds= val_ds.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
for image_batch, labels_batch in dataset.take(1):
    print(image_batch[0].numpy()/255)
pip install preprocessing
resize_and_rescale = tf.keras.Sequential([
    layers.Resizing(IMAGE_SIZE, IMAGE_SIZE),
    layers.Rescaling(1./255),
])
data_augmentation=tf.keras.Sequential([
    layers.RandomFlip("horizontal_and_vertical"),
    layers.RandomRotation(0.2),
])
n_classes=3

Our own Convolutional Neural Network (CNN) for Image Classification

input_shape=(BATCH_SIZE, IMAGE_SIZE,IMAGE_SIZE,CHANNELS)
n_classes=3


model_1= models.Sequential([
    resize_and_rescale,
    data_augmentation,
    layers.Conv2D(32, kernel_size=(3,3), activation='relu', input_shape=input_shape),
    layers.MaxPooling2D((2,2)),
    layers.Conv2D(64, kernel_size=(3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),
    layers.Conv2D(64, kernel_size=(3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),
    layers.Conv2D(64, (3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),
    layers.Conv2D(64, (3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),
    layers.Conv2D(128, (3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),
    layers.Flatten(),
    layers.Dense(256,activation='relu'),
    layers.Dense(n_classes, activation='softmax'),
])
model_1.build(input_shape=input_shape)
model_1.summary()

model_1.compile(
    optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
    metrics=['accuracy']
)
history=model_1.fit(
    train_ds,
    batch_size=BATCH_SIZE,
    validation_data=val_ds,
    verbose=1,
    epochs=50
)
scores=model_1.evaluate(val_ds)

Training History Metrics Extraction

acc=history.history['accuracy']
val_acc=history.history['val_accuracy']


loss=history.history['loss']
val_loss=history.history['val_loss']
history.history['accuracy']

Training History Visualization

EPOCHS=50
plt.figure(figsize=(20,8))
plt.subplot(1,2,1)
plt.plot(range(EPOCHS), acc, label='Training Accuracy')
plt.plot(range(EPOCHS), val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')


plt.subplot(1, 2, 2)
plt.plot(range(EPOCHS), loss, label='Training Loss')
plt.plot(range(EPOCHS), val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

Prediction of Image Labels from Validation Dataset

import numpy as np
for images_batch, labels_batch in val_ds.take(1):
  first_image=images_batch[0].numpy().astype("uint8")
  print("First image to predict")
  plt.imshow(first_image)
  print("Actual Label:",class_names[labels_batch[0].numpy()])


  batch_prediction = model_1.predict(images_batch)
  print("Predicted Label:",class_names[np.argmax(batch_prediction[0])])

def predict(model, img):
  img_array=tf.keras.preprocessing.image.img_to_array(images[i].numpy())
  img_array=tf.expand_dims(img_array,0) #create a batch


  predictions=model.predict(img_array)


  predicted_class=class_names[np.argmax(predictions[0])]
  confidence=round(100*(np.max(predictions[0])),2)
  return predicted_class, confidence
plt.figure(figsize=(15,15))
for images, labels in val_ds.take(1):
  for i in range(1):
    ax=plt.subplot(3,3,i+1)
    plt.imshow(images[i].numpy().astype("uint8"))
    predicted_class, confidence=predict(model_1, images[i].numpy())


    actual_class=class_names[labels[i]]
    plt.title(f"Actual: {actual_class}, \n Predicted: {predicted_class}. \n Confidence: {confidence}%")
    plt.axis("off")

plt.figure(figsize=(15,15))
for images, labels in val_ds.take(1):
  for i in range(9):
    ax=plt.subplot(3,3,i+1)
    plt.imshow(images[i].numpy().astype("uint8"))
    predicted_class, confidence=predict(model_1, images[i].numpy())


    actual_class=class_names[labels[i]]
    plt.title(f"Actual: {actual_class}, \n Predicted: {predicted_class}. \n Confidence: {confidence}%")
    plt.axis("off")

Saving the TensorFlow Model

from tensorflow.keras.models import save_model


# Save the TensorFlow model in .h5 format


# With this line
model_1.save('/kaggle/working/model_potato_50epochs_99%acc.keras')

Evaluating Model Predictions on Validation Dataset

# Initialize lists to store the results
y_true = []
y_pred = []


# Iterate over the validation dataset
for images, labels in val_ds:
    # Get the model's predictions
    predictions = model_1.predict(images)


    # Get the indices of the maximum values along an axis using argmax
    pred_labels = np.argmax(predictions, axis=1)


    # Extend the 'y_true' and 'y_pred' lists
    y_true.extend(labels.numpy())
    y_pred.extend(pred_labels)


# Convert lists to numpy arrays
y_true = np.array(y_true)
y_pred = np.array(y_pred)

Evaluation Metrics Calculation

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score


# Calculate metrics
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred, average='weighted')
recall = recall_score(y_true, y_pred, average='weighted')
f1 = f1_score(y_true, y_pred, average='weighted')


print(f'Accuracy: {accuracy}')  # (accuracy = (TP+TN)/(TP+FP+TN+FN))
print(f'Precision: {precision}')  # (precision = TP/(TP+FP))
print(f'Recall: {recall}')  # (recall = TP/(TP+FN))
print(f'F1 Score: {f1}')  # (f1 score = 2/((1/Precision)+(1/Recall)))

Visualization of Confusion Matrix

import seaborn as sns
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt


# Assuming y_true and y_pred are defined
cm = confusion_matrix(y_true, y_pred)
plt.figure(figsize=(10, 10))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.title('Confusion Matrix')
plt.show()

ROC Curve

from sklearn.metrics import roc_curve, auc
from sklearn.preprocessing import LabelBinarizer
import matplotlib.pyplot as plt


# Binarize the output
lb = LabelBinarizer()
lb.fit(y_true)
y_test = lb.transform(y_true)
y_pred = lb.transform(y_pred)


n_classes = y_test.shape[1]


# Compute ROC curve and ROC area for each class
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_pred[:, i])
    roc_auc[i] = auc(fpr[i], tpr[i])


# Plot all ROC curves
plt.figure()
for i in range(n_classes):
    plt.plot(fpr[i], tpr[i],
             label='ROC curve of class {0} (area = {1:0.2f})'
             ''.format(i, roc_auc[i]))


plt.plot([0, 1], [0, 1], 'k--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic to Multi-Class')
plt.legend(loc="lower right")
plt.show()

AUC Score

from sklearn.metrics import roc_auc_score


# Assuming y_true and y_pred are defined
# 'ovo' stands for One-vs-One
# 'macro' calculates metrics for each label, and finds their unweighted mean
auc = roc_auc_score(y_true, y_pred, multi_class='ovo', average='macro')


print(f'AUC Score: {auc}')  # (AUC Score = Area Under the ROC Curve)

Saving the TensorFlow Model

from tensorflow.keras.models import save_model


# Save the TensorFlow model in .h5 format


# With this line
model_1.save('/kaggle/working/model_potato_50epochs_99%acc1.keras')

CNN Architecture Specification of the Base Research Paper

#Proposed Model in Research Paper
# activation units=64,128,256,512,512,4096,4096,1000
# kernel= 3,3
# max pooling =2,2
input_shape=(224,224,3)

Paper-Based CNN Model Architecture

from tensorflow.keras import Input


model_paper = models.Sequential([
    Input(shape=input_shape),
    resize_and_rescale,
    data_augmentation,
    # conv1
    layers.Conv2D(64, kernel_size=(3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),


    #conv2
    layers.Conv2D(128, kernel_size=(3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),


    #conv3
    layers.Conv2D(256, kernel_size=(3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),


    #conv4
    layers.Conv2D(512, (3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),


    #conv5
    layers.Conv2D(512, (3,3), activation='relu'),
    layers.MaxPooling2D((2,2)),


    layers.Flatten(),
    layers.Dense(4096, activation='relu'),
    layers.Dense(4096, activation='relu'),
    layers.Dense(1000, activation='relu'),
    layers.Dense(n_classes, activation='softmax'),
])
model_paper.summary()

Compilation of the Paper-Based CNN Model

model_paper.compile(
    optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
    metrics=['accuracy']
)

Training the Paper-Based CNN Model

history_paper=model_paper.fit(
    train_ds,
    batch_size=BATCH_SIZE,
    validation_data=val_ds,
    verbose=1,
    epochs=50
)
scores_paper=model_paper.evaluate(val_ds)
acc=history_paper.history['accuracy']
val_acc=history_paper.history['val_accuracy']


loss=history_paper.history['loss']
val_loss=history_paper.history['val_loss']
history_paper.history['accuracy']

Visualization of Training and Validation Metrics of Base Paper Model

EPOCHS=50
plt.figure(figsize=(20,8))
plt.subplot(1,2,1)
plt.plot(range(EPOCHS), acc, label='Training Accuracy')
plt.plot(range(EPOCHS), val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')


plt.subplot(1, 2, 2)
plt.plot(range(EPOCHS), loss, label='Training Loss')
plt.plot(range(EPOCHS), val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

Prediction of Image Label from Validation Dataset

import numpy as np
for images_batch, labels_batch in val_ds.take(1):
  first_image=images_batch[0].numpy().astype("uint8")
  print("First image to predict")
  plt.imshow(first_image)
  print("Actual Label:",class_names[labels_batch[0].numpy()])


  batch_prediction = model_paper.predict(images_batch)
  print("Predicted Label:",class_names[np.argmax(batch_prediction[0])])

def predict(model, img):
  img_array=tf.keras.preprocessing.image.img_to_array(images[i].numpy())
  img_array=tf.expand_dims(img_array,0) #create a batch


  predictions=model.predict(img_array)


  predicted_class=class_names[np.argmax(predictions[0])]
  confidence=round(100*(np.max(predictions[0])),2)
  return predicted_class, confidence
plt.figure(figsize=(15,15))
for images, labels in val_ds.take(1):
  for i in range(1):
    ax=plt.subplot(3,3,i+1)
    plt.imshow(images[i].numpy().astype("uint8"))
    predicted_class, confidence=predict(model_paper, images[i].numpy())


    actual_class=class_names[labels[i]]
    plt.title(f"Actual: {actual_class}, \n Predicted: {predicted_class}. \n Confidence: {confidence}%")
    plt.axis("off")

plt.figure(figsize=(15,15))
for images, labels in val_ds.take(1):
  for i in range(9):
    ax=plt.subplot(3,3,i+1)
    plt.imshow(images[i].numpy().astype("uint8"))
    predicted_class, confidence=predict(model_paper, images[i].numpy())


    actual_class=class_names[labels[i]]
    plt.title(f"Actual: {actual_class}, \n Predicted: {predicted_class}. \n Confidence: {confidence}%")
    plt.axis("off")

Saving the Tensorflow model of the base paper

from tensorflow.keras.models import save_model


# Save the TensorFlow model in .h5 format


# With this line
model_paper.save('/kaggle/working/model_potato_basepaper.keras')
# Initialize lists to store the results
y_true = []
y_pred = []


# Iterate over the validation dataset
for images, labels in val_ds:
    # Get the model's predictions
    predictions = model_paper.predict(images)


    # Get the indices of the maximum values along an axis using argmax
    pred_labels = np.argmax(predictions, axis=1)


    # Extend the 'y_true' and 'y_pred' lists
    y_true.extend(labels.numpy())
    y_pred.extend(pred_labels)


# Convert lists to numpy arrays
y_true = np.array(y_true)
y_pred = np.array(y_pred)

Calculating Classification Metrics

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score


# Calculate metrics
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred, average='weighted')
recall = recall_score(y_true, y_pred, average='weighted')
f1 = f1_score(y_true, y_pred, average='weighted')


print(f'Accuracy: {accuracy}')
print(f'Precision: {precision}')
print(f'Recall: {recall}')
print(f'F1 Score: {f1}')

The provided code segment visualizes the confusion matrix using Seaborn's heatmap function

import seaborn as sns
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt


# Assuming y_true and y_pred are defined
cm = confusion_matrix(y_true, y_pred)
plt.figure(figsize=(10, 10))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.title('Confusion Matrix')
plt.show()

from sklearn.metrics import roc_curve, auc
from sklearn.preprocessing import LabelBinarizer
import matplotlib.pyplot as plt


# Binarize the output
lb = LabelBinarizer()
lb.fit(y_true)
y_test = lb.transform(y_true)
y_pred = lb.transform(y_pred)


n_classes = y_test.shape[1]


# Compute ROC curve and ROC area for each class
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_pred[:, i])
    roc_auc[i] = auc(fpr[i], tpr[i])


# Plot all ROC curves
plt.figure()
for i in range(n_classes):
    plt.plot(fpr[i], tpr[i],
             label='ROC curve of class {0} (area = {1:0.2f})'
             ''.format(i, roc_auc[i]))


plt.plot([0, 1], [0, 1], 'k--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic to Multi-Class')
plt.legend(loc="lower right")
plt.show()

from sklearn.metrics import roc_auc_score


# Assuming y_true and y_pred are defined
# 'ovo' stands for One-vs-One
# 'macro' calculates metrics for each label, and finds their unweighted mean
auc = roc_auc_score(y_true, y_pred, multi_class='ovo', average='macro')


print(f'AUC Score: {auc}')  # (AUC Score = Area Under the ROC Curve)

Using Explainable AI to explain the predictions of our own CNN model,Taking an image and predicting it's class using our own CNN Model

import numpy as np
import matplotlib.pyplot as plt


for images_batch, labels_batch in val_ds.take(1):
  first_image = images_batch[0].numpy().astype("uint8")
  print("First image to predict")
  plt.imshow(first_image)
  print("Actual Label:", class_names[labels_batch[0].numpy()])


  batch_prediction = model_1.predict(images_batch)
  top_3_pred_indices = np.argsort(batch_prediction[0])[-3:][::-1]
  top_3_pred_labels = [class_names[index] for index in top_3_pred_indices]
  top_3_pred_values = [batch_prediction[0][index] for index in top_3_pred_indices]
  top_3_pred_percentages = [value * 100 for value in top_3_pred_values]
  print("Top 3 Predicted Labels:", top_3_pred_labels)
  print("Top 3 Predicted Probabilities (%):", top_3_pred_percentages)


  # Plotting the top 3 predictions
  plt.figure(figsize=(6, 3))
  plt.bar(top_3_pred_labels, top_3_pred_percentages)
  plt.title('Top 3 Predictions')
  plt.xlabel('Classes')
  plt.ylabel('Prediction Probabilities (%)')
  plt.show()

Model Explainability with LIME (Local Interpretable Model-Agnostic Explanations)

pip install lime

Setting up Lime for Image Explanation

%load_ext autoreload
%autoreload 2
import os,sys
try:
    import lime
except:
    sys.path.append(os.path.join('..', '..')) # add the current directory
    import lime
from lime import lime_image
explainer = lime_image.LimeImageExplainer()
%%time
# Hide color is the color for a superpixel turned OFF. Alternatively, if it is NONE, the superpixel will be replaced by the average of its pixels
explanation = explainer.explain_instance(images_batch[0].numpy().astype('double'), model_1.predict, top_labels=3, hide_color=0, num_samples=1000)
from skimage.segmentation import mark_boundaries

Superpixel for the top most Prediction

#here hide_rest is True
temp, mask = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=3, hide_rest=True)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

#here hide_rest is False
temp, mask = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=10, hide_rest=False)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

Visualizing 'pros and cons'

temp, mask = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=False, num_features=10, hide_rest=False)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

temp, mask = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=False, num_features=1000, hide_rest=False, min_weight=0.1)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

Explaination Heatmap plot with weights

#Select the same class explained on the figures above.
ind =  explanation.top_labels[0]


#Map each explanation weight to the corresponding superpixel
dict_heatmap = dict(explanation.local_exp[ind])
heatmap = np.vectorize(dict_heatmap.get)(explanation.segments)


#Plot. The visualization makes more sense if a symmetrical colorbar is used.
plt.imshow(heatmap, cmap = 'RdBu', vmin  = -heatmap.max(), vmax = heatmap.max())
plt.colorbar()

Second Prediction in the List

temp, mask = explanation.get_image_and_mask(explanation.top_labels[1], positive_only=True, num_features=5, hide_rest=True)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

Rest of the image from the second prediction i.e. top_labels[1]

temp, mask = explanation.get_image_and_mask(explanation.top_labels[1], positive_only=True, num_features=5, hide_rest=False)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

Visualizing 'pros and cons'

temp, mask = explanation.get_image_and_mask(explanation.top_labels[1], positive_only=False, num_features=10, hide_rest=False)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

temp, mask = explanation.get_image_and_mask(explanation.top_labels[1], positive_only=False, num_features=1000, hide_rest=False, min_weight=0.1)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

#Select the same class explained on the figures above.
ind =  explanation.top_labels[1]


#Map each explanation weight to the corresponding superpixel
dict_heatmap = dict(explanation.local_exp[ind])
heatmap = np.vectorize(dict_heatmap.get)(explanation.segments)


#Plot. The visualization makes more sense if a symmetrical colorbar is used.
plt.imshow(heatmap, cmap = 'RdBu', vmin  = -heatmap.max(), vmax = heatmap.max())
plt.colorbar()

from lime import lime_image
explainer = lime_image.LimeImageExplainer()
explanation = explainer.explain_instance(images_batch[0].numpy().astype('double'), model_1.predict,top_labels=3, hide_color=0, num_samples=1000)
from skimage.segmentation import mark_boundaries


temp_1, mask_1 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=5, hide_rest=True)
temp_2, mask_2 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=False, num_features=10, hide_rest=False)


fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15,15))
ax1.imshow(mark_boundaries(temp_1, mask_1))
ax2.imshow(mark_boundaries(temp_2, mask_2))
ax1.axis('off')
ax2.axis('off')


plt.savefig('mask_default.png')

工学博士,担任《Mechanical System and Signal Processing》《中国电机工程学报》《控制与决策》等期刊审稿专家,擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

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

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

相关文章

2024年电子工程与自动化技术国际会议(ICEEAT 2024)

2024 International Conference on Electronic Engineering and Automation Technology 【1】大会信息 会议简称:ICEEAT 2024 大会地点:中国西安 审稿通知:投稿后2-3日内通知 【2】会议简介 2024年电子工程与自动化技术国际会议是聚焦电子…

11 IP协议 - IP协议头部

什么是 IP 协议 IP(Internet Protocol)是一种网络通信协议,它是互联网的核心协议之一,负责在计算机网络中路由数据包,使数据能够在不同设备之间进行有效的传输。IP协议的主要作用包括寻址、分组、路由和转发数据包&am…

Elasticsearch之深入聚合查询

1、正排索引 1.1 正排索引(doc values )和倒排索引 概念:从广义来说,doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作,所有的数字、地理坐标、日期、IP 和不分词( no…

IT闲谈-Kylin入门教程

目录 一、引言二、Kylin简介三、环境准备四、安装与配置五、数据导入与建模六、查询与分析七、总结 一、引言 Apache Kylin是一个开源的分布式分析引擎,旨在提供Hadoop/Spark之上的SQL接口及多维分析(OLAP)能力以支持超大规模数据。Kylin通过…

计算机毕业设计项目、管理系统、可视化大屏、大数据分析、协同过滤、推荐系统、SSM、SpringBoot、Spring、Mybatis、小程序项目编号1-500

大家好,我是DeBug,很高兴你能来阅读!作为一名热爱编程的程序员,我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里,我将会结合实际项目经验,分享编程技巧、最佳实践以及解决问题的方法。无论你是…

设计模式-工厂方法(创建型)

创建型-工厂方法 简单工厂 将被创建的对象称为“产品”,将生产“产品”对象称为“工厂”;如果创建的产品不多,且不需要生产新的产品,那么只需要一个工厂就可以,这种模式叫做“简单工厂”,它不属于23中设计…

樱花动漫2024最新网页地址链接

大家好!今天我要为大家种草一个非常棒的动漫资源在线平台——樱花动漫网页。作为一个网络文化研究者,我一直在关注当代动漫文化的发展和传播方式。而樱花动漫网页正是我近期发现的一颗璀璨明珠,它不仅为动漫爱好者提供了一个交流、分享的平台…

2.数人数

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/431 题目描述 在一个班级里,男生比女生多…

mysql 更改数据存储目录

先停止 mysql :sudo systemctl start/stop mysql 新建新的目录, 比如 /mnt/data/systemdata/mysql/mysql_data sudo chown -R mysql:mysql /mnt/data/sysdata/mysql/mysql_data sudo chmod -R 750 /mnt/data/sysdata/mysql/mysql_data 更改mysql.cnf…

【设计模式】行为型设计模式之 职责链模式,探究过滤器、拦截器、Mybatis插件的底层原理

一、介绍 职责链模式在开发场景中经常被用到,例如框架的过滤器、拦截器、还有 Netty 的编解码器等都是典型的职责链模式的应用。 标准定义 GOF 定义:将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求,将这些接收对象…

联合体和枚举类型

1.联合体 1.1 联合体类型的声明 像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。 但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同⼀块内存空间。所以联合体也叫:共用体。 给联合体…

数据并非都是正态分布:三种常见的统计分布及其应用

你有没有过这样的经历?使用一款减肥app,通过它的图表来监控自己的体重变化,并预测何时能达到理想体重。这款app预测我需要八年时间才能恢复到大学时的体重,这种不切实际的预测是因为应用使用了简单的线性模型来进行体重预测。这个…

C++ list链表的使用和简单模拟实现

目录 前言 1. list的简介 2.list讲解和模拟实现 2.1 默认构造函数和push_back函数 2.2 迭代器实现 2.2.1 非const正向迭代器 2.2.2 const正向迭代器 2.2.3 反向迭代器 2.3 插入删除函数 2.3.1 insert和erase 2.3.2 push_back pop_back push_front pop_front 2.4 构…

LLVM Cpu0 新后端3

想好好熟悉一下llvm开发一个新后端都要干什么,于是参考了老师的系列文章: LLVM 后端实践笔记 代码在这里(还没来得及准备,先用网盘暂存一下): 链接: https://pan.baidu.com/s/1V_tZkt9uvxo5bnUufhMQ_Q?…

173.二叉树:找树左下角的值(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr, right(nullptr) {}* Tree…

强!推荐一款开源接口自动化测试平台:AutoMeter-API !

在当今软件开发的快速迭代中,接口自动化测试已成为确保代码质量和服务稳定性的关键步骤。 随着微服务架构和分布式系统的广泛应用,对接口自动化测试平台的需求也日益增长。 今天,我将为大家推荐一款强大的开源接口自动化测试平台: AutoMete…

【中国开源生态再添一员】天工AI开源自家的Skywork

刚刚看到《AI高考作文出圈,网友票选天工AI居首》,没想到在Huggingface中发现了Skywork大模型。天工大模型由昆仑万维自研,是国内首个对标ChatGPT的双千亿级大语言模型,天工大模型通过自然语言与用户进行问答式交互,AI生…

用c语言实现通讯录

目录 静态简易通讯录 代码: 功能模块展示: 设计思路: 动态简易通讯录(本质顺序表) 代码: 扩容模块展示: 设计思路: 文件版本通讯录 代码: 文件模块展示&#x…

突破网络屏障:掌握FRP内网穿透技术

1.FRP介绍 1.frp是什么 frp 是一款高性能的反向代理应用,专注于内网穿透。它支持多种协议,包括 TCP、UDP、HTTP、HTTPS 等,并且具备 P2P 通信功能。使用 frp,您可以安全、便捷地将内网服务暴露到公网,通过拥有公网 I…

【C++ STL】模拟实现 string

标题:【C :: STL】手撕 STL _string 水墨不写bug (图片来源于网络) C标准模板库(STL)中的string是一个可变长的字符序列,它提供了一系列操作字符串的方法和功能。 本篇文章,我们将模拟实现STL的…