基于Intel Ai Analytics Toolkit 及边缘计算的溶氧预测水产养殖监测方案

基于AI的淡水养殖水质溯源、优化系统方案

  • 前言
  • 一、关键需求及方案概述
  • 二、方案设计
    • 预测机制
    • LSTM 模型
    • 基于intel AI 的时序水质分析模型与分类模型优化
  • 三、实战分析
    • 1、方案简述
    • 2、数据分析
      • 预处理
      • 特征类型处理
      • 特征分布分析
    • 3、特征构造
    • 4、特征选择
      • 过滤法
      • 重要性排序
    • 5.构建LSTM模型
    • 6.模型训练
  • 四、Intel Ai Analytics Toolkit 及相关库使用
    • Intel ® Modin
    • Intel ® Extension for Scikit-learn
    • Intel daal4py
    • Intel ® XGBoost
    • Intel ® Extension for PyTorch
    • 功耗更低,速度更快的Tesla T4
  • 总结


前言

![在这里插入图片描述](https://img-blog.csdnimg.cn/a87fadcbd3af4387a47ef77244fccd15.png
近年来水产品总产量逐年上升。由于日本排海事件的发酵及不良营销,水产品供需发生变化,淡水水产需求增大,所以加强水产养殖的信息化建设,建立水产养殖监测、预警和管理的综合体系显得十分重要 。水质的安全关乎水产养殖的产量和质量,在养殖过程中,对水质实现动态的监测和预警能提升养殖过程的稳健性。 传统的水质监测系统,存在系统精度低,系统控制延迟高,不能进行预测和提前预警等问题。
本次Intel 黑客松大赛,我基于Intel Ai Analytics Toolkit 及边缘计算设备实现溶氧预测水产养殖监测方案。

一、关键需求及方案概述

传统水产养殖水质监测系统具有不能提前预警、通信延迟高的问题,对于时序数据处理能力较差,核心需解决的是时序数据的分析处理能力。
在这里插入图片描述

该方案以基于Intel优化的 水质预测算法为核心,针对于不同场景的特征分布进行定向分析,实现水质溯源档案、重金属富集预测、溶氧预测、水华预警预测、兽药残留检测等功能。

其中时序数据,通过物联数据采集模块实现水质数据采集和端处理的功能,采样周期为 1 min。 采集系统电路连接多种传感器获取模拟信号,经过 MCU 识别和计算后将结果值保存到本地寄存器,作为上报的原始数据。
使用Intel Ai Analytics Toolkit 通过对采集数据的处理、分析、训练、预测、实现预测模型。

二、方案设计

预测机制

应用边缘计算的方法,将云服务器的计算和控制任务卸载到上位机,来降低系统控制延迟。 上位机系统实现数据预测的功能,当数据预测或采集数据中出现预警值时,上位机及时向增氧机发出增氧的指令,防范水中出现低氧的情况。 上位机系统配置有预测进程和数据收发进程,两个进程并行计算。同时,上报至云服务的数据会进行二次分析,进行日级别的重金属富集、水华预警预测、兽药残留预测、环境污染检测等模型分析。
下面是溶氧预测的流畅图。
在这里插入图片描述

LSTM 模型

长短时记忆网络( Long short-term memory,LSTM )是一种循环神经网络 (Recurrent neural network, RNN)的特殊变体,具有“门”结构,通过门单元的逻辑控制决定数据是否更新或是选择丢弃,克服了 RNN 权重影响过大、容易产生梯度消失和爆炸的缺点,使网络可以更好、更快地收敛,能够有效提高预测精度。LSTM 拥有三个门, 分别为遗忘门、输入门、输出门,以此决定每一时刻信息记忆与遗忘。输入门决定有多少新的信息加入到细胞当中,遗忘门控制每一时刻信息是否会被遗忘,输出门决定每一时刻是否有信息输出。其基本结构如图所示。
在这里插入图片描述

基于intel AI 的时序水质分析模型与分类模型优化

通过针对预测水域质量的数据集,我们从多个角度对其展开分析,包括不限于缺失值分析、异常值分析、不规则分布分析、离散/连续数据分析等。

在分析过程中,我们使用了,
英特尔® Modin 分发版提升pandas处理与探索数据;
英特尔® Extension for Scikit-learn提升基线模型(SVM等)的执行效率;
英特尔® 架构优化的 XGBoost作为我们最终的分类模型进行效果的提升与验证。

三、实战分析

1、方案简述

根据物联设备(本次使用的是开源数据模拟)获取的数据集进行特征构造,用于预测目标水域质量,围绕特征与目标间的关联表现进行特征筛选,利用英特尔® Modin 分发版提升pandas处理特征集的效率,得到了50维相关特征作为最终的入模特证。最后,利用英特尔® 架构优化的XGBoost模型进行二分类。
完成模型后,使用Intel Extension for PyTorch提供的分布式训练功能,利用多台机器和多GPU进行训练。通过使用ipex.distributed.DistributedDataParallel()来包装模型,并在Tesla T4GPU上并行训练数据。

环境配置:
在这里插入图片描述
在这里插入图片描述

2、数据分析

预处理

首先,获取一份水质监测的离线数据,针对于后续可能实现的污染监测、重金属富集,加入一些随机特征进行模拟。然后将该数据集按照5:2.5:2.5的比例划分为训练集、验证集、测试集。测试集仅在模型推理阶段时使用,可以防止数据穿越等问题的发生,并能够准确对模型关于预测目标的拟合效果进行评估。

特征类型处理

1、划分类别特征, 数值特征

# 划分类别特征, 数值特征
cat_cols, float_cols = [], ['Target']
for col in data.columns:
    if data[col].value_counts().count() < 50:
        cat_cols.append(col)
    else:
        float_cols.append(col)
print('离散特征:', cat_cols)
print('连续特征:', float_cols)

离散特征: [‘Color’, ‘Source’, ‘Month’, ‘Day’, ‘Time of Day’, ‘Target’]
连续特征: [‘Target’, ‘pH’, ‘Iron’, ‘Nitrate’, ‘Chloride’, ‘Lead’, ‘Zinc’…]

2、针对离散特征,进行缺失值处理

# 查看缺失值情况
display(data[cat_cols].isna().sum())
missing=data[cat_cols].isna().sum().sum()
print("\nThere are {:,.0f} missing values in the data.".format(missing))
print('-' * 50)

其中像月份属于有序类别特征,如果单纯地映射数字会破坏掉这种有序性,对于这类数据进行单独映射。

......
# 将月份映射至数字1~12
months = ["January", "February", "March", "April", "May",
          "June", "July", "August", "September", "October",
          "November", "December"]
data['Month'] = data['Month'].replace(dict(zip(months, range(1, len(months) + 1))))
display(data['Month'].value_counts())
......

针对明显无序的类别特征,我们对其进行独特编码处理。对于有序类别特征,我们不对其进行额外处理。

......
# 将无序类别特征进行独特编码
color_ohe = OneHotEncoder()
X_color = color_ohe.fit_transform(data.Color.values.reshape(-1, 1)).toarray()
pickle.dump(color_ohe, open('../feat_data/color_ohe.pkl', 'wb'))     # 将编码方式保存在本地
dfOneHot = pandas.DataFrame(X_color, columns=["Color_" + str(int(i)) for i in range(X_color.shape[1])])
data = pandas.concat([data, dfOneHot], axis=1)
......

由于连续变量存在数据缺失的情况,所以我们通过统计每个连续类别对应的中位数对缺失值进行填充。

display(data[float_cols].isna().sum())
missing=data[float_cols].isna().sum().sum()
print("\nThere are {:,.0f} missing values in the data.".format(missing))

# 使用中位数填充连续变量每列缺失值
fill_dict = {}
for column in list(data[float_cols].columns[data[float_cols].isnull().sum() > 0]):
    tmp_list = list(data[column].dropna())
    # 平均值
    mean_val = sum(tmp_list) / len(tmp_list)

    # 中位数
    tmp_list.sort()
    mid_val = tmp_list[len(tmp_list) // 2]
    if len(tmp_list) % 2 == 0:
        mid_val = (tmp_list[len(tmp_list) // 2 - 1] + tmp_list[len(tmp_list) // 2]) / 2

    fill_val = mid_val

    # 填充缺失值
    data[column] = data[column].fillna(fill_val)
    fill_dict[column] = fill_val

特征分布分析

# 针对每个连续变量的频率画直方图
data[float_cols].hist(bins=50,figsize=(16,12))

在这里插入图片描述

对于非常不规则的数据进行非线性变换。

# 针对不规则分布的变量进行非线性变换,一般进行log
log_col = ['Iron', 'Zinc', 'Turbidity', 'Copper', 'Manganese']
show_col = []
for col in log_col:
    data[col + '_log'] = np.log(data[col])
    show_col.append(col + '_log')
    
# 特殊地,由于Lead变量0值占据了一定比例,此处特殊处理Lead变量
excep_col = ['Lead']
spec_val = {}
# 先将0元素替换为非0最小值,再进行log变换
for col in excep_col:
    spec_val[col] = data.loc[(data[col] != 0.0), col].min()
    data.loc[(data[col] == 0.0), col] = data.loc[(data[col] != 0.0), col].min()
    data[col + '_log'] = np.log(data[col])
    show_col.append(col + '_log')
    
data[show_col].hist(bins=50,figsize=(16,12))

在这里插入图片描述
可以发现,上述不规则分布的变量经过log之后已经变成了模型更容易拟合的类正态分布。

3、特征构造

由于特征之间往往隐藏着很多相关的信息等待挖掘,此处进行特征关联,得到新的特征。由于时间关系,此处我们仅以类别特征进行分组,去依次统计其余特征在组内的中位数、均值、方差、最大值、最小值、计数特征,挖掘有效的交互特征。

...... 
# 特征交互统计
cat_interaction_dict = {}
del_feat_list = []
if 'del_feat_list' in count_fea_dict:
    del_feat_list = count_fea_dict['del_feat_list']
add_feat_list = []
    
for cat_col1 in cat_cols:
    if cat_col1 == label_col:
        continue
    new_col = cat_col1 + '_count'
    if new_col not in data.columns and new_col not in del_feat_list:
        add_feat_list.append(new_col)
        temp = data.groupby(cat_col1).size()
        cat_interaction_dict[new_col] = dict(temp)
        temp = temp.reset_index().rename(columns={0: new_col})
        data = data.merge(temp, 'left', on=cat_col1)
    for cat_col2 in cat_cols:
        if cat_col2 == label_col:
            continue
        if cat_col1 == cat_col2:
            continue
        new_col = cat_col1 + '_' + cat_col2 + '_count'
        if new_col not in data.columns and new_col not in del_feat_list:
            add_feat_list.append(new_col)
            temp = data.groupby(cat_col1)[cat_col2].nunique()
            cat_interaction_dict[new_col] = dict(temp)
            temp = temp.reset_index().rename(columns={cat_col2: new_col})
            data = data.merge(temp, 'left', on=cat_col1)
...... 

4、特征选择

过滤法

由于本次目标是对淡水质量是否可用进行二分类预测,所以我们针对包含构造特征的所有特征数据,对于离散特征,利用卡方检验判断特征与目标的相关性,对于连续特征,利用方差分析判断特征与目标的相关性,以此做特征集的第一轮筛选。

# 卡方检验对类别特征进行筛选
def calc_chi2(x, y):
    import pandas as pd
    import numpy as np
    from scipy import stats
    
    chi_value, p_value, def_free, exp_freq = -1, -1, -1, []
    tab = pd.crosstab(x, y)
    if tab.shape == (2, 2):
        # Fisher确切概率法, 2✖️2列联表中推荐使用Fisher检验
        oddsr, p_value = stats.fisher_exact(tab, alternative='two-sided')
    else:
        # Pearson卡方检验, 参数correction默认为True
        chi_value, p_value, def_free, exp_freq = stats.chi2_contingency(tab, correction=False)

        min_exp = exp_freq.min()
        if min_exp >= 1 and min_exp < 5:
            # Yates校正卡方检验
            chi_value, p_value, def_free, exp_freq = stats.chi2_contingency(tab, correction=True)
    
    return chi_value, p_value, def_free, exp_freq

def select_feat_by_chi2(df, cate_cols, target_col, alpha=0.05, cut=99999):
    col_chi2_list = []
    for col in cate_cols:
        chi_value, p_value, def_free, exp_freq = calc_chi2(df[col], df[target_col])
        if p_value < alpha:
            col_chi2_list.append([col, chi_value])
    col_chi2_list = sorted(col_chi2_list, key=lambda x: x[1], reverse=False)
    rel_cols = []
    for i in range(min(len(col_chi2_list), cut)):
        rel_cols.append(col_chi2_list[i][0])
    return rel_cols
            
data = {
    'a': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
    'b': [2000, 2001, 2002, 2001, 2000, 2002],
    'Target': [0, 0, 1, 1, 1, 0]
}
df = pd.DataFrame(data)
cols = ['a', 'b']
select_feat_by_chi2(df, cols, 'Target')

# 方差分析法对连续特征进行筛选
def calc_fc(x, y):
    import pandas as pd
    import statsmodels.api as sm
    from statsmodels.formula.api import ols
    
    tab = pd.DataFrame({'group': y, 'feat': x})
    tab['group'] = tab['group'].astype('str').map(lambda x: 'g_' + x)

    mod = ols('feat ~ group', data=tab).fit()        
    ano_table = sm.stats.anova_lm(mod, typ=2)
    F = ano_table.loc['group', 'F']
    p_value = ano_table.loc['group', 'PR(>F)']
    return F, p_value

def select_feat_by_fc(df, cate_cols, target_col, alpha=0.05, cut=99999):
    from scipy import stats
    
    col_F_list = []
    for col in cate_cols:
        F, p_value = calc_fc(df[col], df[target_col])
        F_test = stats.f.ppf((1-alpha), 
                             df[target_col].nunique(),
                             len(df[col]) - df[target_col].nunique())
        # p值小于显著性水平 or MSa/MSe大于临界值,则拒绝原假设,认为各组样本不完全来自同一总体
        if p_value < alpha or F > F_test:
            col_F_list.append([col, F])
    col_F_list = sorted(col_F_list, key=lambda x: x[1], reverse=False)
    rel_cols = []
    for i in range(min(len(col_F_list), cut)):
        rel_cols.append(col_F_list[i][0])
    return rel_cols

data = {
    'a': [0.13, 0.09, 0.2, 0.11, 0.13, 0.15],
    'b': [2000, 2001, 2002, 2001, 2000, 2002],
    'Target': [0, 0, 1, 1, 1, 0]
}
df = pd.DataFrame(data)
cols = ['a', 'b']
select_feat_by_fc(df, cols, 'Target')

重要性排序

针对第一轮筛选剩余的150维特征,使用模型去进行拟合,并根据最后模型产出的特征重要性从大到小排序,根据重要性以及设定阈值对特征进行第二轮筛选。

# 模型训练函数
def train(data):
    ## Prepare Train and Test datasets ##
    print("Preparing Train and Test datasets")
    X_train, X_test, y_train, y_test = prepare_train_test_data(data=data,
                                                               target_col='Target',
                                                               test_size=.25)
    
    ## Initialize XGBoost model ##
    ratio = float(np.sum(y_train == 0)) / np.sum(y_train == 1)
    parameters = {
        'scale_pos_weight': len(raw_data.loc[raw_data['Target'] == 0]) / len(raw_data.loc[raw_data['Target'] == 1]),
        'objective': "binary:logistic", 
        'learning_rate': 0.1,
        'n_estimators': 18,
        'max_depth': 10,
        'min_child_weight': 5,
        'alpha': 4,
        'seed': 1024,
    }
    xgb_model = XGBClassifier(**parameters)
    xgb_model.fit(X_train, y_train)

    print("Done!\nBest hyperparameters:", grid_search.best_params_)
    print("Best cross-validation accuracy: {:.2f}%".format(grid_search.best_score_ * 100))
    
    ## Convert XGB model to daal4py ##
    xgb = grid_search.best_estimator_
    daal_model = d4p.get_gbt_model_from_xgboost(xgb.get_booster())

    ## Calculate predictions ##
    daal_prob = d4p.gbt_classification_prediction(nClasses=2,
                                                  resultsToEvaluate="computeClassLabels|computeClassProbabilities",
                                                  fptype='float').compute(X_test,
                                                                          daal_model).probabilities  # or .predictions
    xgb_pred = pd.Series(np.where(daal_prob[:, 1] > .5, 1, 0), name='Target')
    xgb_acc = accuracy_score(y_test, xgb_pred)
    xgb_auc = roc_auc_score(y_test, daal_prob[:, 1])
    xgb_f1 = f1_score(y_test, xgb_pred)

    ## Plot model results ##
    print("\ndaal4py Test ACC: {:.2f}%, F1 Accuracy: {:.2f}%, AUC: {:.5f}".format(xgb_acc * 100, xgb_f1 * 100, xgb_auc))
    # plot_model_res(model_name='XGBoost', y_test=y_test, y_prob=daal_prob[:, 1])

    importance_df = pd.DataFrame({'importance':xgb.feature_importances_,'feat_name': data.drop('Target', axis=1).columns})
    importance_df = importance_df.sort_values(by='importance', ascending=False)
    
    return importance_df

importance_df = train(data)
display(importance_df.head())

针对现有的150维特征对XGB模型进行拟合,并针对输出的特征重要性得分进行排序,将小于阈值的特征进行过滤。
在这里插入图片描述

5.构建LSTM模型

LSTM 模型的关键是单元状态,即贯穿图表顶部的水平线。 每个单元就像一个微型状态机,单元三个门的权重在训练过程中学习得到。 遗忘门是
主要由 σ 层组成,σ 层根据 ht-1 和 xt 的输入,通过 sigmoid 激活函数计算信息的丢弃情况,生成一个 0 到 1 之间的结果 ft,0 表示全部丢弃,1 表示
全部保留。 ft 用于与 Ct-1 输入矩阵做点乘运算。 输入门会生成新的信息存储到单元状态中,主要由 σ 层和 tanh 层决定。 通过运算,单元状态从 Ct-1 更新为 Ct。 输出门决定输出的结果,由 σ 层、tanh 层和更新后的单元状态 Ct 共同决定。
在这里插入图片描述

其中: ft、it∗C􀮨t、ht 分别表示 t 时刻单元中遗忘门、输入门、输出门的结果; σ 为 sigmoid 激活函数; W为权重; ht-1 、xt 为 单元输入; bf、bi、bc、bo 均为偏差矩阵;tanh 表示激活函数; Ct-1 为初始单元状态; Ct 为更新后的单元状态; ht 为单元的状态输出;ot 表示输出的信息量

将时间序列转换为监督学习问题
将时间序列形式的数据转换为监督学习集的形式,例如:[[10],[11],[12],[13],[14]]转换为[[0,10],[10,11],[11,12],[12,13],[13,14]],即把前一个数作为输入,后一个数作为对应输出。

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j + 1, i)) for j in range(n_vars)]
        # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j + 1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j + 1, i)) for j in range(n_vars)]
    # put it all together
    agg = concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg
 
reframed = series_to_supervised(scaled, 2, 1)

初始化LSTM模型,设置神经元核心的个数,迭代次数,优化器等等

model = Sequential()
model.add(LSTM(27, input_shape=(train_X.shape[1], train_X.shape[2])))
model.add(Dropout(0.5))
model.add(Dense(15,activation='relu'))#激活函数
model.compile(loss='mae', optimizer='adam')
history = model.fit(train_X, train_y, epochs=95, batch_size=2, validation_data=(test_X, test_y), verbose=2,shuffle=False)

6.模型训练

针对经过两轮筛选得到的50维入模特征,使用RandomizedSearchCV对XGBoost的重要参数进行搜索,同时使用StratifiedKFold对模型效果进行交叉验证。

......
import modin.pandas as pd
from modin.config import Engine
Engine.put("dask")
......
from sklearn.preprocessing import OneHotEncoder
from sklearnex import patch_sklearn
patch_sklearn()
......
from sklearn.model_selection import train_test_split, StratifiedKFold, GridSearchCV, RandomizedSearchCV
from sklearn.preprocessing import RobustScaler, StandardScaler
from sklearn.metrics import make_scorer, recall_score, precision_score, accuracy_score, roc_auc_score, f1_score
from sklearn.metrics import roc_auc_score, roc_curve, auc, accuracy_score, f1_score
from sklearn.metrics import precision_recall_curve, average_precision_score
from sklearn.svm import SVC
from xgboost import plot_importance
import pickle
......
# 模型训练函数
def train(data):
    ## Prepare Train and Test datasets ##
    print("Preparing Train and Test datasets")
    X_train, X_test, y_train, y_test = prepare_train_test_data(data=data,
                                                               target_col='Target',
                                                               test_size=.25)
    
    ## Initialize XGBoost model ##
    ratio = float(np.sum(y_train == 0)) / np.sum(y_train == 1)
    parameters = {
        'scale_pos_weight': len(raw_data.loc[raw_data['Target'] == 0]) / len(raw_data.loc[raw_data['Target'] == 1]),
        'objective': "binary:logistic", 
        'learning_rate': 0.1,
        'n_estimators': 18,
        'max_depth': 10,
        'min_child_weight': 5,
        'alpha': 4,
        'seed': 1024,
    }
    xgb_model = XGBClassifier(**parameters)

    ## Tune hyperparameters ##
    strat_kfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=21)
    print("\nTuning hyperparameters..")
    grid = {'min_child_weight': [1, 5, 10],
            'gamma': [0.5, 1, 1.5, 2, 5],
            'max_depth': [15, 17, 20],
    
    strat_kfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=1024)
    grid_search = RandomizedSearchCV(xgb_model, param_distributions=grid, 
                                    cv=strat_kfold, n_iter=10, scoring='accuracy', 
                                    verbose=1, n_jobs=-1, random_state=1024)
    grid_search.fit(X_train, y_train)

    print("Done!\nBest hyperparameters:", grid_search.best_params_)
    print("Best cross-validation accuracy: {:.2f}%".format(grid_search.best_score_ * 100))
    
    ## Convert XGB model to daal4py ##
    xgb = grid_search.best_estimator_
    daal_model = d4p.get_gbt_model_from_xgboost(xgb.get_booster())

    ## Calculate predictions ##
    daal_prob = d4p.gbt_classification_prediction(nClasses=2,
                                                  resultsToEvaluate="computeClassLabels|computeClassProbabilities",
                                                  fptype='float').compute(X_test,
                                                                          daal_model).probabilities  # or .predictions
    xgb_pred = pd.Series(np.where(daal_prob[:, 1] > .5, 1, 0), name='Target')
    xgb_acc = accuracy_score(y_test, xgb_pred)
    xgb_auc = roc_auc_score(y_test, daal_prob[:, 1])
    xgb_f1 = f1_score(y_test, xgb_pred)

    ## Plot model results ##
    print("\ndaal4py Test ACC: {:.2f}%, F1 Accuracy: {:.2f}%, AUC: {:.5f}".format(xgb_acc * 100, xgb_f1 * 100, xgb_auc))
    # plot_model_res(model_name='XGBoost', y_test=y_test, y_prob=daal_prob[:, 1])

    ##
    importance_df = pd.DataFrame({'importance':xgb.feature_importances_,'feat_name': data.drop('Target', axis=1).columns})
    importance_df = importance_df.sort_values(by='importance', ascending=False)
    print('model saving...')
    pickle.dump(xgb, open("../result/model_best.dat", "wb"))
    return importance_df

四、Intel Ai Analytics Toolkit 及相关库使用

Intel ® Modin

本方案使用了Intel ® Modin 分发版提升pandas处理与探索数据;Intel 为Pandas库提供了基于Dask的并行计算功能。通过配置引擎,代码将使用Dask作为默认的并行计算引擎,在使用Pandas或Modin进行数据处理和分析时,将利用Dask的分布式计算能力来加速操作。

Intel ® Extension for Scikit-learn

本方案使用 Intel® Extension for Scikit-learn的目的是提升基线模型(SVM等)的执行效率;

其中,包含使用Intel scikit-learn的StandardScaler进行特征缩放,并使用train_test_split函数进行数据集分割。在完成分割后,函数还将scaler对象保存到文件中,并打印训练集的形状。同时使用了intel优化的NearestNeighbors、RobustScaler等类进行聚类、分类、标准化动作。

Intel daal4py

在oneAPI提供的daal4py模型的加速下,算法的推理速度能得到了更大的提升,同时,在特征选择和模型训练中,当数据集的某些特性不符合特定条件时,需要应用特定的补丁来处理这些特性。PatchingConditionsChain 类提供了一种方便的方式来创建和管理这些补丁条件链。

Intel ® XGBoost

Intel XGBoost的XGBClassifier是一个基分类器,它使用XGBoost算法进行分类任务。该分类器默认使用gbtree作为基分类器,并支持并行计算处理。XGBClassifier和XGBRegressor类提供了nthread参数,用于在训练期间可以使用的线程数。
我们通过调整模型的nthread、n_estimators、learning_rate等参数来优化模型的性能。

Intel ® Extension for PyTorch

首先,使用Intel Scikit-learn库提供的预处理函数来对数据进行归一化,以加速神经网络的训练。可以使用sklearn_ipydnn.Normalize()函数对输入数据进行归一化。
然后,使用Intel Scikit-learn库提供的优化器来替换PyTorch的优化器。例如,sklearn_ipydnn.Adam()函数来替换PyTorch的Adam优化器。这些优化器针对Intel MKL进行了优化,可以加速训练过程。

功耗更低,速度更快的Tesla T4

在这里插入图片描述

完成模型后,使用Intel Extension for PyTorch提供的分布式训练功能,利用多台机器和多GPU进行训练。通过使用ipex.distributed.DistributedDataParallel()来包装模型,并在Tesla T4 GPU上并行训练数据。

将数据加载到GPU内存中,以加速数据传输和处理。可以使用PyTorch的torch.cuda.is_available()函数检查是否有可用的GPU,然后使用.to(device)方法将数据和模型移动到GPU上。

总结

在这里插入图片描述
最终,我们经过多次训练,模型在训练集的平均准确率约91.42%,验证集上的准确率达到90.89%,针对单条数据的推理时间为0.03s。针对特殊处理出来的测试集上准确率达到91.21%,最高准确率可达92.99%。上图是其中一次训练结果的展示结果,该结果有力地验证了本模型的有效性。

上述方案我们规划并实现了一个简单的淡水养殖水质溯源系统,同时采用了Intel ® Modin 、Intel ® Extension for Scikit-learn、 Intel daal4py、Intel ® XGBoost、Intel ® Extension for PyTorch、Tesla T4加速等多种手段,大大提高了推理速度和系统鲁棒性,验证了我们提出模型的有效性、高效性、可行性。

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

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

相关文章

java游戏攻略资讯网站的设计与实现springboot+vue

游戏攻略网站分为管理员与用户两种角色。 管理员的功能包括登录&#xff0c;用户管理&#xff0c;游戏分类管理&#xff0c;游戏攻略管理&#xff0c;游戏资讯管理等。 登录功能&#xff1a;管理员需要登录进入系统后台。 用户管理&#xff1a;实现用户信息的查询&#xff0c;修…

TCP 重传、滑动窗口、流量控制、拥塞控制

1&#xff1a;重传机制 超时重传 快速重传 SACK 方法 Duplicate SACK 1&#xff1a;重传机制 超时重传&#xff1a;重传机制的其中一个方式&#xff0c;就是在发送数据时&#xff0c;设定一个定时器&#xff0c;当超过指定的时间后&#xff0c;没有收到对方的ACK确认应答报文…

vue3 中使用 sse 最佳实践,封装工具

工具 // 接受参数 export interface SSEChatParams {url: string,// sse 连接onmessage: (event: MessageEvent) > void,// 处理消息的函数onopen: () > void,// 建立连接触发的事件finallyHandler: () > void,// 相当于 try_finally 中的 finally 部分&#xff0c;不…

读书笔记-《数据结构与算法》-摘要1[数据结构]

文章目录 [数据结构]1. String - 字符串2. Linked List - 链表2.1 链表的基本操作2.1.1 反转链表单向链表双向链表 2.1.2 删除链表中的某个节点2.1.3 链表指针的鲁棒性2.1.4 快慢指针 3. Binary Tree - 二叉树3.1 树的遍历3.2 Binary Search Tree - 二叉查找树 4. Queue - 队列…

JDK21无法导入TimeUnit类

运行环境&#xff1a;windows11、IDEA2023.1.3、JDK21 问题描述&#xff1a;IDEA中无法导入java.util.concurrent.TimeUnit类。 以下截图是问题解决后的截图。有问题的时候未截图&#xff0c;说明一下&#xff0c;有问题的时候TimeUnit类是红色的&#xff0c;无法导入&#x…

申请开通QMT量化需要多少资金?免费开通!

最近量化交易在市场上大火&#xff0c;很多投资者想要参与进来。QMT量化软件是目前市场上一款比较常见并且强大的量化软件。那开通QMT量化交易软件需要多少资金&#xff1f; QMT量化交易软件是一种专门用于量化交易的工具&#xff0c;它能够帮助投资者通过程序化交易策略进行股…

布隆过滤器

目录 布隆过滤器的提出 布隆过滤器的概念 布隆过滤器的实现 布隆过滤器的插入 布隆过滤器的查找 布隆过滤器的删除 布隆过滤器的优点 布隆过滤器的缺点 布隆过滤器的使用场景 布隆过滤器的提出 在注册账号设置昵称的时候,为了保证每个用户的昵称唯一性,系统必须检测…

庆科EMW3080wifi模组烧录AT固件

本文记录庆科的EMW3080wifi模组烧写AT固件的过程&#xff1b; 参考文档&#xff1a;https://mxchip.yuque.com/zc9vym/tn0rwo/kgs4lx?singleDoc#NrlEB 以上链接为庆科方提供的文档&#xff0c;如有侵权立即删除&#xff1b; 庆科官方提供了三种烧录方式&#xff0c;我这边只记…

Quirks(怪癖)模式是什么?它和 Standards(标准)模式有什么区别?

前言: "Quirks模式"和"Standards模式"是与HTML文档渲染模式相关的两种模式。它们影响着浏览器如何解释和渲染HTML和CSS。理解它们之间的区别对于前端开发者和网页设计师来说是至关重要的。本文将深入讨论Quirks模式和Standards模式的区别&#xff0c;以及它…

如何快速了解一家公司?

在炒股过程中&#xff0c;我们想要了解一家公司是否具有投资价值&#xff0c;需要查看和阅读很多公司的相关资料。股民们自行去查询往往会花费很多的时间精力&#xff0c;所以专业的炒股软件一般都会给股民提供这些现成的资料。 在金斗云智投APP内&#xff0c;进入到个股详情页…

知识管理平台Confluence:win10安装confluence

文章目录 介绍主要功能 安装教程安装java运行平台JRE安装数据库Postgresql在Postgresql创建confluence使用的数据库创建数据库用户创建数据库 安装confluence注册confluence启动confluence 参考链接 介绍 Confluence 是由澳大利亚软件公司 Atlassian 开发的企业协作平台。它提…

负电源电压转换-TP7660H

负电源电压转换-TP7660H 简介引脚说明典型应用电路倍压与反压的应用电路 简介 TP7660H 是一款 DC/DC 电荷泵电压反转器专用集成电路。芯片能将输入范围为 2.5V&#xff5e;11V 的电压转换成相应的-2.5V&#xff5e;-11V 的输出&#xff0c;电压转换精度可达99.9%&#xff0c;电…

2022年高校大数据挑战赛B题图像信息隐藏求解全过程论文及程序

2022年高校大数据挑战赛 B题 图像信息隐藏 原题再现&#xff1a; 互联网的快速发展&#xff0c;给图像、视频的传播方式带来巨大变化。图像作为媒体的重要载体&#xff0c;每天有大量的原创图像公开在互联网上&#xff0c;如何保护图像版权的同时不破坏原始的图像一直是图像处…

MySQL 索引,优化,回表,执行计划等相关总结学习

一、MySQL 执行流程 innoDB表引擎&#xff1a;默认的事务型引擎&#xff0c;最重要最广泛的存储引擎&#xff0c;性能非常优秀,数据村粗在共享表空间&#xff0c;可以通过配置分开,主键查询性能高于其他引擎 myISM表引擎&#xff1a;5.1版本前这个是默认的存储引擎&#xff0c…

inBuilder低代码平台新特性推荐-第十二期

各位CSDN的友友们&#xff0c;大家好~ 今天来给大家介绍一下inBuilder低代码平台社区版中特性推荐系列第十二期——新版本集成开发环境&#xff01; 01 概述 编码规则定义规定了编号的生成格式&#xff0c;一条编码规则定义由基本信息和段列表组成&#xff1a;基本信息是对该编…

OCR原理解析

目录 1.概述 2.应用场景 3.发展历史 4.基于传统算法的OCR技术原理 4.1 图像预处理 4.1.1 灰度化 4.1.2 二值化 4.1.3 去噪 4.1.4 倾斜检测与校正 4.1.4.2 轮廓矫正 4.1.5 透视矫正 4.2 版面分析 4.2.1 连通域检测文本 4.2.2 MSER检测文本 4.3 字符切割 4.3.1 连…

视频后期特效处理软件 Motion 5 mac中文版

Motion mac是一款运动图形和视频合成软件&#xff0c;适用于Mac OS平台。 Motion mac软件特点 - 精美的效果&#xff1a;Motion提供了多种高质量的运动图形和视频效果&#xff0c;例如3D效果、烟雾效果、粒子效果等&#xff0c;方便用户制作出丰富多彩的视频和动画。 - 高效的工…

【力扣 面试题02.07链表相交】一种思路极其清晰的解法

力扣一单简单题&#xff0c;看完大佬的题解真是佩服得五体投地&#xff01; 虽是一道简单题&#xff0c;当我吭哧吭哧写了几十行后&#xff0c;看到大佬仅仅几行直接秒掉&#xff0c;只能说算法的本质还是数学&#xff0c;数学逻辑思维真是太重要了&#xff0c;有时候真得慢慢去…

TZOJ 1429 小明A+B

答案&#xff1a; #include <stdio.h> int main() {int T0, A0, B0, sum0;scanf("%d", &T); //输入测试数据的组数while (T--) //循环T次{scanf("%d %d", &A, &B); //输入AB的值sum A B;if (sum > 100) //如果是三位数{…

使用 Go 构建高性能的命令行工具

命令行工具&#xff08;CLI&#xff09;在软件开发中扮演着重要的角色&#xff0c;尤其是在自动化工具、开发工具链和服务器管理等领域。Go 语言以其简洁性和高性能而闻名&#xff0c;非常适合用来创建强大且高效的 CLI 工具。本文将详细介绍如何使用 Go 语言来构建 CLI 应用&a…