在11月1日的“甲骨文数据库与云系列公益讲座”中,向大家介绍了如何在 Oracle Database 23ai 中运行人工智能模型。讲座后的一周里,收到了大量咨询,大家关注的焦点之一就是:如何在本地运行的 Oracle 数据库中部署自建的、专为企业定制的机器学习模型。有些客户甚至直接分享了具体应用场景,希望 Oracle 能提供相关的解决方案。
为此,今天我将通过一个实战案例,为大家展示如何在 10分钟内 将当前的机器学习模型迁移至 Oracle Database 23ai,并顺利运行。让我们一起看看如何利用 Oracle 强大的数据库功能,实现 AI 模型的快速部署,助力企业数据价值的全面释放!
今天,我们设定一个应用场景:一家为客户提供商品和服务的公司,需要对当前的客户进行评级,由于数据量很大,当前的操作是将Oracle Database 当作数据的容器,每次运行客户评级任务时,都需要从数据库中读取大量的数据到当前的机器学习环境中,然后进行推理。由于数据量大,当前机器学习环境以Python为主,因此每次推理都将耗费大量的时间。客户向Oracle咨询,可否将当前的推理模型放入Oracle数据库内部,从而加快推理过程,简化数据流程?并且可否给出一个可行性验证方案?
答案是肯定的,我们可以轻松地将您现有的基于Python、R以及其他可以转换为onnx格式的模型放入数据库中,只通过SQL对该模型进行调用并进行推理。
首先,让我们看看用于训练模型的测试数据(这份数据来自网络)是什么样子的?
我们可以看到,该训练数据由8068条, 有9个Features,以及一个Target(Segmentation),从字段名称上可以判断,这些Feature表示该用户基本信息。我们将使用这些测试数据,进行模型训练。
接下来,我们将使用这些训练数据,构建并训练模型,这是一个分类问题,因此我们将使用简单的神经网络分类算法。由于该程序比较简单,就不为您做程序解释。您可以根据自己的需要,使用适合您自己应用场景的模型和算法。这里需要注意的是,目前Oracle Database 23ai支持的外部模型格式为onnx,因此在程序的末尾,您需要将您训练好的模型保存为onnx格式。
在下面的代码清单中,我们首先导入了必要的软件包,然后加载数据并进行预处理,其中我们使用SimpleImputer 填充数值列的缺失值,然后填充类别列的缺失值并编码。接下来是对数据进行分离,分离出特征和目标,并按照8/2的比例对数据进行分割,分割为训练集和测试集。接下来就是将数据转换为张量,然后进行模型、损失函数以及优化器的初始化,并训练模型。
import pandas as pdimport torchimport torch.nn as nnimport torch.optim as optimfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import LabelEncoderfrom sklearn.impute import SimpleImputerfrom torch.utils.data import DataLoader, TensorDatasetimport onnximport torch.onnxtrain_data_path = 'Train.csv'train_data = pd.read_csv(train_data_path)imputer = SimpleImputer(strategy='median')train_data[['Work_Experience', 'Family_Size']] = imputer.fit_transform(train_data[['Work_Experience', 'Family_Size']])label_encoders = {}for column in ['Gender', 'Ever_Married', 'Graduated', 'Profession', 'Spending_Score', 'Var_1']:train_data[column].fillna(train_data[column].mode()[0], inplace=True)le = LabelEncoder()train_data[column] = le.fit_transform(train_data[column])label_encoders[column] = lele = LabelEncoder()train_data['Segmentation'] = le.fit_transform(train_data['Segmentation'])label_encoders['Segmentation'] = leX = train_data.drop(columns=['ID', 'Segmentation']).valuesy = train_data['Segmentation'].valuesX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)X_train_tensor = torch.tensor(X_train, dtype=torch.float32)y_train_tensor = torch.tensor(y_train, dtype=torch.long)X_val_tensor = torch.tensor(X_val, dtype=torch.float32)y_val_tensor = torch.tensor(y_val, dtype=torch.long)class SimpleNNClassifier(nn.Module):def __init__(self, input_size, num_classes):super(SimpleNNClassifier, self).__init__()self.fc1 = nn.Linear(input_size, 64)self.fc2 = nn.Linear(64, 32)self.fc3 = nn.Linear(32, num_classes)def forward(self, x):x = torch.relu(self.fc1(x))x = torch.relu(self.fc2(x))return self.fc3(x)model = SimpleNNClassifier(input_size=X_train.shape[1], num_classes=len(le.classes_))criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(model.parameters(), lr=0.001)epochs = 10for epoch in range(epochs):model.train()optimizer.zero_grad()outputs = model(X_train_tensor)loss = criterion(outputs, y_train_tensor)loss.backward()optimizer.step()print(f"Epoch {epoch+1}/{epochs}, Loss: {loss.item()}")
当模型训练好之后,我们需要将模型转换为onnx格式。
onnx_file_path = "nn_classifier_model.onnx"dummy_input = torch.randn(1, X_train.shape[1], dtype=torch.float32)torch.onnx.export(model,dummy_input,onnx_file_path,input_names=['input'],output_names=['output'],opset_version=11,dynamic_axes={'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}})print(f"ONNX模型已保存到 {onnx_file_path}")
上述程序运行之后,将得到如下结果:
由于我们今天关注的重点是如何在Oracle Database 23ai中运行自己的人工智能模型,因此我们没有对模型进行优化,请忽略上面那些不理想的模型表现。
当我们得到onnx格式的模型之后,我们接下来要做的就是将模型上传到Oracle Database 23ai所在的服务器。今天我们使用的环境是运行在我的笔记本虚拟机中的Oracle Database 23ai,具体版本信息如下所示:
我将刚刚生成的onnx格式的模型放在/u01下面,并在数据库中创建一个目录对象,DM_DUMP指向/u01,然后授予用户的读写权限。
接下来只需要通过一段简短的PL/SQL代码即可将该模型导入数据库中。其中代码的18行,我们设定了模型在数据库中的名称,20-26行需要注意,这里设定的是模型导入时的参数,21行表明该模型是一个分类模型,23行则定义了后续使用模型进行推理时,要给出的特征名称,建议与稍后使用的数据表字段信息保持一致。
DECLAREm_blob BLOB default empty_blob();m_src_loc BFILE;BEGINDBMS_LOB.createtemporary(m_blob, FALSE);m_src_loc := BFILENAME('DM_DUMP', 'nn_classifier_model.onnx');DBMS_LOB.fileopen(m_src_loc, DBMS_LOB.file_readonly);DBMS_LOB.loadfromfile(m_blob, m_src_loc, DBMS_LOB.getlength(m_src_loc));DBMS_LOB.CLOSE(m_src_loc);DBMS_DATA_MINING.import_onnx_model('henry_BYOM_test',m_blob,JSON('{"function": "classification","input": {"input": ["Gender", "Ever_Married", "Age", "Graduated", "Profession", "Work_Experience", "Spending_Score", "Family_Size", "Var_1"]}}'));DBMS_LOB.freetemporary(m_blob);END;/
我们成功导入模型之后,就可以在数据库内部通过SQL语句直接使用该模型了。我们创建一个为模型提供特征数据的表,建表语句如下:
CREATE TABLE test1108 (ID NUMBER,Gender NUMBER,Ever_Married NUMBER,Age NUMBER,Graduated NUMBER,Profession NUMBER,Work_Experience NUMBER,Spending_Score NUMBER,Family_Size NUMBER,Var_1 NUMBER);
接下来向该表中插入测试数据。我们可以看到该测试表中有2627条测试数据。
接下来我们就可以使用SQL语句调用模型了。其中PREDICTION(henry_BYOM_test using *)的含义是调用test1108表中的所有字段作为feature,并调用模型henry_BYOM_test进行推理。需要注意的是,我们没有对模型进行优化,甚至也没有进行特征工程,因为很显然ID字段是对预测没有帮助的干扰信息,我们应该在模型训练之前将其删除。
SELECT id,PREDICTION(henry_BYOM_test using *) PREDICT_client_level from test1108;
在上图中显示了用户的ID以及根据我们的模型为该客户预测的客户评分。
就是如此简单,只需简单的几个步骤,不到十分钟的时间,就可以将您自己的机器学习模型部署到本地运行的Oracle Database 23ai中。Oracle Database 23ai不只能载入传统的机器学习模型,LLM用的embedding模型等都可以载入,具体信息您可以观看11月1日公开课的视频回放,或咨询Oracle技术顾问。
相关链接:Oracle Database 23ai:在Oracle数据库中运行用户自定义的AI模型
想了解更多资讯
扫码关注👇

了解更多考试相关
扫码添加上智启元官方客服微信👇

17认证网








