• [技术干货] 快速体验:基于卷积神经网络的艺术品瑕疵检测与修复
    前言卷积神经网络具有优秀的特征提取能力和模式识别能力。在艺术品瑕疵检测中,可以利用CNN对艺术品的图像进行高效的分析和判别。通过训练神经网络,能够学习到各种瑕症的特征,包括裂纹、褪色、污渍等,从而实现对艺术品图像的自动化检测。实战体验模型:import tensorflow as tf from tensorflow.keras import layers, models # 构建卷积神经网络模型 model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(img_height, img_width, img_channels))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu')) # 在模型中添加全连接层和输出层 model.add(layers.Flatten()) model.add(layers.Dense(128, activation='relu')) model.add(layers.Dense(num_classes, activation='softmax')) # 编译模型 model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # 训练模型 model.fit(train_images, train_labels, epochs=num_epochs, validation_data=(val_images, val_labels))通过检测到的瑕疵信息,然后利用图像处理和深度学习技术实现对艺术品图像的瑕疵修复。例如,生成对抗网络(GAN)可以通过学习艺术品图像的分布,生成具有艺术品特征的新图像,从而实现对瑕的修复。以下是一个简单的案例代码,演示如何使用卷积神经网络(CNN)进行艺术品瑕疵检测。本案例很基础,实际应用中需要更多的数据、更复杂的模型和更多的训练才能满足需求。import tensorflow as tf from tensorflow.keras import layers, models from tensorflow.keras.preprocessing import image from tensorflow.keras.preprocessing.image import ImageDataGenerator import matplotlib.pyplot as plt import numpy as np # 数据准备 train_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( 'path_to_dataset', # 替换为你的数据集路径 target_size=(150, 150), batch_size=32, class_mode='binary' ) # 构建卷积神经网络模型 model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu')) model.add(layers.Flatten()) model.add(layers.Dense(128, activation='relu')) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) # 模型训练 history = model.fit(train_generator, epochs=10) # 可视化训练过程 acc = history.history['accuracy'] epochs = range(1, len(acc) + 1) plt.plot(epochs, acc, 'bo', label='Training accuracy') plt.title('Training accuracy') plt.xlabel('Epochs') plt.ylabel('Accuracy') plt.legend() plt.show() # 进行瑕疵检测 def predict_defect(image_path): img = image.load_img(image_path, target_size=(150, 150)) img_array = image.img_to_array(img) img_array = np.expand_dims(img_array, axis=0) img_array /= 255.0 prediction = model.predict(img_array) if prediction[0] < 0.5: print("艺术品存在瑕疵") else: print("艺术品正常") # 替换为测试图像的路径 test_image_path = 'path_to_test_image.jpg' predict_defect(test_image_path)path_to_dataset替换为你的训练数据集路径path_to_test_image.jpg替换为需要进行瑕疵检测的测试图像路径基于卷积神经网络的艺术品瑕疵检测:import numpy as np import matplotlib.pyplot as plt from tensorflow.keras.models import Sequential, Model from tensorflow.keras.layers import Conv2D, Input, UpSampling2D, concatenate from tensorflow.keras.preprocessing.image import load_img, img_to_array, array_to_img from tensorflow.keras.optimizers import Adam # 数据准备 def load_data(): # 在实际应用中,你需要准备一个包含正常和瑕疵图像的大型数据集 # 这里使用一个简化的例子,加载两张示意图像 img_normal = img_to_array(load_img('path_to_normal_image.jpg', target_size=(256, 256))) / 255.0 img_defective = img_to_array(load_img('path_to_defective_image.jpg', target_size=(256, 256))) / 255.0 return np.array([img_normal]), np.array([img_defective]) # 构建瑕疵检测模型 def build_detection_model(): model = Sequential() model.add(Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=(256, 256, 3))) model.add(Conv2D(64, (3, 3), activation='relu', padding='same')) model.add(Conv2D(1, (3, 3), activation='sigmoid', padding='same')) return model # 构建瑕疵修复模型 def build_restoration_model(): input_layer = Input(shape=(256, 256, 3)) x = Conv2D(64, (3, 3), activation='relu', padding='same')(input_layer) x = Conv2D(64, (3, 3), activation='relu', padding='same')(x) encoded = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x) return Model(input_layer, encoded) # 构建完整的瑕疵检测与修复模型 def build_combined_model(detection_model, restoration_model): restoration_model.trainable = False combined_model = Sequential() combined_model.add(restoration_model) combined_model.add(detection_model) return combined_model # 训练模型 def train_models(detection_model, restoration_model, combined_model, img_normal, img_defective): detection_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) restoration_model.compile(optimizer='adam', loss='mse') # 训练瑕疵检测模型 detection_model.fit(img_defective, np.ones_like(img_defective), epochs=10) # 训练瑕疵修复模型 restoration_model.fit(img_normal, img_defective, epochs=10) # 训练整合模型 combined_model.compile(optimizer='adam', loss=['mse', 'binary_crossentropy']) combined_model.fit(img_normal, [img_defective, np.ones_like(img_defective)], epochs=10) # 测试模型 def test_model(combined_model, img_normal): restored_img, _ = combined_model.predict(img_normal) plt.figure(figsize=(10, 5)) plt.subplot(1, 2, 1) plt.title('Original Image') plt.imshow(array_to_img(img_normal[0])) plt.subplot(1, 2, 2) plt.title('Restored Image') plt.imshow(array_to_img(restored_img[0])) plt.show() # 主程序 img_normal, img_defective = load_data() detection_model = build_detection_model() restoration_model = build_restoration_model() combined_model = build_combined_model(detection_model, restoration_model) train_models(detection_model, restoration_model, combined_model, img_normal, img_defective) test_model(combined_model, img_normal)基于生成对抗网络(GAN)的方法进行艺术品瑕检测与修这个代码使用了 CIFAR-10数据集,通过生成对抗网络在图像上添加随机瑕疵,并尝试修复这些瑕疵。import numpy as np import matplotlib.pyplot as plt from tensorflow.keras.models import Sequential, Model from tensorflow.keras.layers import Input, Conv2D, LeakyReLU, BatchNormalization, Flatten, Dense, Reshape, Conv2DTranspose from tensorflow.keras.optimizers import Adam from tensorflow.keras.datasets import cifar10 # 加载并预处理数据集 def load_and_preprocess_data(): (x_train, _), (_, _) = cifar10.load_data() x_train = x_train / 255.0 return x_train[:5000] # 在图像上生成随机瑕疵 def add_random_defects(images): defect_mask = np.random.random(size=images.shape) < 0.05 images[defect_mask] = np.random.random(size=defect_mask.sum()) return images # 构建生成器模型 def build_generator(latent_dim): model = Sequential() model.add(Dense(4 * 4 * 256, input_dim=latent_dim)) model.add(Reshape((4, 4, 256))) model.add(Conv2DTranspose(128, kernel_size=4, strides=2, padding="same")) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.2)) model.add(Conv2DTranspose(64, kernel_size=4, strides=2, padding="same")) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.2)) model.add(Conv2DTranspose(3, kernel_size=4, strides=2, padding="same", activation="sigmoid")) return model # 构建判别器模型 def build_discriminator(input_shape): model = Sequential() model.add(Conv2D(64, kernel_size=4, strides=2, padding="same", input_shape=input_shape)) model.add(LeakyReLU(alpha=0.2)) model.add(Conv2D(128, kernel_size=4, strides=2, padding="same")) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.2)) model.add(Flatten()) model.add(Dense(1, activation="sigmoid")) return model # 构建生成对抗网络模型 def build_gan(generator, discriminator): discriminator.trainable = False model = Sequential() model.add(generator) model.add(discriminator) return model # 编译判别器和生成对抗网络模型 def compile_models(generator, discriminator, gan): discriminator.compile(optimizer=Adam(lr=0.0002, beta_1=0.5), loss="binary_crossentropy", metrics=["accuracy"]) gan.compile(optimizer=Adam(lr=0.0002, beta_1=0.5), loss="binary_crossentropy") # 训练模型 def train_models(generator, discriminator, gan, data, latent_dim, epochs=10000, batch_size=64): batch_count = data.shape[0] // batch_size for epoch in range(epochs): for _ in range(batch_count): noise = np.random.normal(0, 1, size=(batch_size, latent_dim)) generated_images = generator.predict(noise) real_images = data[np.random.randint(0, data.shape[0], size=batch_size)] labels_real = np.ones((batch_size, 1)) labels_fake = np.zeros((batch_size, 1)) d_loss_real = discriminator.train_on_batch(real_images, labels_real) d_loss_fake = discriminator.train_on_batch(generated_images, labels_fake) d_loss = 0.5 * np.add(d_loss_real, d_loss_fake) noise = np.random.normal(0, 1, size=(batch_size, latent_dim)) labels_gan = np.ones((batch_size, 1)) g_loss = gan.train_on_batch(noise, labels_gan) # 打印损失 print(f"Epoch {epoch}/{epochs} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]") # 每 1000 次迭代保存并显示生成的图像 if epoch % 1000 == 0: save_generated_images(generator, epoch) # 保存生成的图像 def save_generated_images(generator, epoch, examples=10, dim=(1, 10), figsize=(10, 1)): noise = np.random.normal(0, 1, size=(examples, 100)) generated_images = generator.predict(noise) generated_images = generated_images.reshape(examples, 32, 32, 3) plt.figure(figsize=figsize) for i in range(generated_images.shape[0]): plt.subplot(dim[0], dim[1], i+1) plt.imshow(generated_images[i], interpolation="nearest") plt.axis("off") plt.tight_layout() plt.savefig(f"generated_image_epoch_{epoch}.png") # 主程序 latent_dim = 100 input_shape = (32, 32, 3) # 加载并预处理数据 data = load_and_preprocess_data() # 在图像上生成随机瑕疵 data_with_defects = add_random_defects(np.copy(data)) # 构建生成器、判别器和生成对抗网络模型 generator = build_generator(latent_dim) discriminator = build_discriminator(input_shape) gan = build_gan(generator, discriminator) # 编译模型 compile_models(generator, discriminator, gan) # 训练模型 train_models(generator, discriminator, gan, data_with_defects, latent_dim)总结深度学习技术在艺术品瑕疵检测与修复领域的应用为文化遗产保护带来了新的视角和可能性。通过生成对抗网络(GAN)等技术,能够实现更高精度的瑕疵检测和自动化的修复流程。这不仅提升了修复效率,还为文化遗产的数字化和数据驱动保存提供了新的途径。
  • [技术干货] Sora文生视频:重新定义视频创作的边界
    前言随着数字技术的飞速进步,视频创作已经从专业领域的专属工具,逐渐转变为大众皆可参与的创意表达平台。而在这个变革的浪潮中,Sora文生视频凭借其独特的技术优势和创新的理念,正重新定义着视频创作的边界。Sora文生视频不仅仅是一个视频编辑工具,它更是一个集创意、协作与分享于一体的综合性平台。通过Sora,用户可以轻松地将自己的想法和故事转化为生动的视频作品,与全世界分享自己的创意和热情。一、技术驱动的创意表达Sora文生视频拥有强大的技术支撑,其基于深度学习的图像处理和语音识别技术,使得视频编辑变得更加智能化和高效。用户无需具备专业的视频制作技能,只需要通过简单的拖拽和选择,就能实现复杂的视频剪辑和特效制作。在Sora平台上,用户可以轻松调整视频的色彩、光线和构图,实现电影级的视觉效果。同时,平台还提供了丰富的音效库和背景音乐选择,让视频作品更加生动和感人。除了基础的编辑功能,Sora还支持AI驱动的自动化编辑。通过智能识别视频内容,Sora能够自动添加合适的特效、转场和字幕,大大提升了视频制作的效率和便捷性。二、协作与分享的社区精神Sora文生视频非常注重用户之间的协作与分享。平台提供了多人在线编辑功能,使得团队成员可以实时协作,共同完成一个视频项目。这种协作模式不仅提高了工作效率,也让创意的碰撞和融合成为可能。同时,Sora还建立了一个充满活力的创作者社区。在这个社区里,用户可以浏览和分享其他创作者的作品,互相学习、互相启发。这种分享和互动的精神,让Sora成为了一个创意的聚集地,吸引着越来越多的创作者加入其中。三、教育与培训的广阔应用除了个人创作者和团队协作,Sora文生视频在教育和培训领域也有着广泛的应用。教师可以利用Sora平台制作生动有趣的课件和教学视频,提高学生的学习兴趣和效果。学生也可以利用Sora平台自主创作学习视频,巩固和拓展学科知识。此外,Sora还可以作为企业和机构的内部培训工具。通过制作定制化的培训视频,企业可以更加高效地进行员工培训和能力提升。四、展望未来随着技术的不断发展和市场的不断拓展,Sora文生视频的未来充满了无限可能。首先,随着5G、云计算等技术的普及,视频创作和分享将变得更加便捷和高效。Sora平台将能够支持更高清、更流畅的视频制作和分享,为用户提供更加优质的视频体验。其次,随着AI技术的不断进步,Sora的自动化编辑功能将更加智能和精准。未来,我们甚至可以期待通过语音或文字描述,就能自动生成高质量的视频作品。最后,随着全球创作者社区的不断扩大和成熟,Sora将成为一个真正的全球创意交流平台。在这个平台上,不同文化、不同背景的创作者可以相互碰撞、相互学习,共同推动视频创作艺术的进步和发展。结语Sora文生视频以其独特的技术优势和创新的理念,正在重新定义视频创作的边界。它不仅提供了一个高效便捷的视频编辑工具,更建立了一个充满活力和创意的社区。在这个平台上,每个人都可以成为创作者,用视频表达自己的想法和故事。随着技术的不断进步和市场的不断拓展,我相信Sora文生视频将会在未来继续引领视频创作的新潮流,为我们带来更多惊喜和感动。
  • [问题求助] yolov5成功安装算法App,但检测不出来结果,有没有一个嵌入成功并且可检测的模型,需要排查一下问题。
     什么报错的信息都没有,就是检测框不出来。
  • [问题求助] 80分类coco128数据集子训练yolov5,成功安装App,但检测不出来结果
    已经成功嵌入到相机里面了, 就是检测不出结果。是不是中间有什么坑!请问是为什么?
  • [问题求助] 在ECS windows部署Llama2 尝试使用MLC运行,但出现以下报错,求助
    在ECS windows部署Llama2 尝试使用MLC运行,但出现以下报错,求助
  • [技术干货] 2024年1月人工智能问题总结合集
    一月问题总结如下:【1】用华为atlas300-3010 用于训练失败cid:link_3【2】如何展示这些图片呢cid:link_4【3】云平台第一次用,求助怎么导入transformers库啊?cid:link_0【4】 atlas 200 DK 制卡完成后启动不了cid:link_1【5】请问下,新人申请预测大模型一般几天可以通过申请。cid:link_2
  • [技术干货] AI Gallery在线分析影评情感基调
    1.AI Gallery1.1 AI Gallery简介AI Gallery是在ModelArts的基础上构建的开发者生态社区,提供了Notebook代码样例、数据集、算法、模型、Workflow等AI数字资产的共享,为高校科研机构、AI应用开发商、解决方案集成商、企业级/个人开发者等群体,提供安全、开放的共享及交易环节,加速AI资产的开发与落地,保障AI开发生态链上各参与方高效地实现各自的商业价值。AI Gallery文档:cid:link_0AI Gallery中的代码样例平台:cid:link_11.2 AI Gallery前提准备1.2.1 输入中文电影进行样例搜索1.2.2 点击Run in ModelArts1.2.3 选择环境1.3 AI Gallery在线分析影评情感基调样例代码使用1.3.1 准备代码和数据相关代码、数据和模型都已存放在OBS中,执行下面一段代码即可将其拷贝到Notebook中import osimport moxing as moxif not os.path.exists("/home/ma-user/work/xx"): mox.file.copy_parallel('obs://modelarts-labs-bj4-v2/case_zoo/bert_ch_movie_reviews/bert_movie_ch.zip',"/home/ma-user/work/bert_movie_ch.zip") os.system("cd /home/ma-user/work;unzip bert_movie_ch.zip;rm bert_movie_ch.zip") if os.path.exists("/home/ma-user/work/bert_movie_ch"): print('Download success') else: raise Exception('Download Failed')else: print("Project already exists")执行完成之后会出现Download success。1.3.2 安装所需要的python模块1.3.3 导包及超参设置导包import numpy as npimport randomimport torchimport matplotlib.pyplot as pltfrom torch.nn.utils import clip_grad_norm_from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSamplerfrom transformers import BertTokenizer, BertForSequenceClassification, AdamWfrom transformers import get_linear_schedule_with_warmupimport warningswarnings.filterwarnings('ignore')切换路径# 进入项目路径%cd /home/ma-user/work/bert_movie_ch超参数设置# 超参数设置SEED = 123BATCH_SIZE = 16LEARNING_RATE = 2e-5WEIGHT_DECAY = 1e-2EPSILON = 1e-8random.seed(SEED)np.random.seed(SEED)torch.manual_seed(SEED)1.3.4 数据处理1.3.4.1 获取文本内容# 读取文件,返回文件内容def readfile(filename): with open(filename, encoding="utf-8") as f: content = f.readlines() return content# 正负情感语料pos_text = readfile('./data/pos.txt')neg_text = readfile('./data/neg.txt')sentences = pos_text + neg_textpos_textlen(pos_text)1.3.4.2 转换成数组长度# label encoderpos_targets = np.ones((len(pos_text))) # -->1neg_targets = np.zeros((len(neg_text))) # -->0targets = np.concatenate((pos_targets, neg_targets), axis=0).reshape(-1, 1) targets.shapepos_targetsneg_targets# 转换为tensortotal_targets = torch.tensor(targets)total_targets.shape1.3.4.3 加载模型进行分词# 从预训练模型中加载bert-base-chinese# [UNK] 特征 [CLS]起始 [SEP]结束tokenizer = BertTokenizer.from_pretrained('bert-base-chinese', cache_dir="./transformer_file/")tokenizerprint(pos_text[1])# 进行分词print(tokenizer.tokenize(pos_text[1]))# bert编码,会增加开始[CLS]--101 和 结束[SEP]--102标记print(tokenizer.encode(pos_text[1]))# 将bert编码转换为 字print(tokenizer.convert_ids_to_tokens(tokenizer.encode(pos_text[1])))tokenizer.encode("我")1.3.4.4 句子转数字进行编码#将每个句子转成数字(大于126做截断,小于126做PADDING,加上首尾两个标识,长度总共等于128)def convert_text_to_token(tokenizer, sentence, limit_size=126): tokens = tokenizer.encode(sentence[:limit_size]) # 直接截断 if len(tokens) < limit_size + 2: # 补齐(pad的索引号就是0) tokens.extend([0] * (limit_size + 2 - len(tokens))) return tokens# 对每个句子进行编码input_ids = [convert_text_to_token(tokenizer, x) for x in sentences]# 放到tensor中input_tokens = torch.tensor(input_ids)print(input_tokens.shape)input_tokens[1]1.3.4.5 建立mask# 建立maskdef attention_masks(input_ids): atten_masks = [] for seq in input_ids: # 如果有编码(>0)即为1, pad为0 seq_mask = [float(x>0) for x in seq] atten_masks.append(seq_mask) return atten_masks# 生成attention_masksatten_masks = attention_masks(input_ids)# 将atten_masks放到tensor中attention_tokens = torch.tensor(atten_masks)print(attention_tokens)print(attention_tokens.size())print('input_tokens:\n', input_tokens) # shape=[7360, 128]print('total_targets:\n', total_targets) # shape=[7360, 1]print('attention_tokens:\n', attention_tokens) # shape=[7360, 128]1.3.4.6 切分from sklearn.model_selection import train_test_split# 使用random_state固定切分方式,切分 train_inputs, train_labels, train_masks,train_inputs, test_inputs, train_labels, test_labels = train_test_split(input_tokens, total_targets, random_state=2022, test_size=0.2)train_masks, test_masks, _, _ = train_test_split(attention_tokens, input_tokens, random_state=2022, test_size=0.2)print(train_inputs.shape, test_inputs.shape) #torch.Size([8000, 128]) torch.Size([2000, 128])print(train_masks.shape, test_masks.shape) #torch.Size([8000, 128])和train_inputs形状一样print(train_inputs[0])print(train_masks[0])1.3.4.7 打包# 使用TensorDataset对tensor进行打包train_data = TensorDataset(train_inputs, train_masks, train_labels)# 无放回地随机采样样本元素train_sampler = RandomSampler(train_data)train_dataloader = DataLoader(train_data, sampler=train_sampler, batch_size=BATCH_SIZE)test_data = TensorDataset(test_inputs, test_masks, test_labels)test_sampler = SequentialSampler(test_data)test_dataloader = DataLoader(test_data, sampler=test_sampler, batch_size=BATCH_SIZE)# 查看dataloader内容for i, (train, mask, label) in enumerate(train_dataloader): #torch.Size([16, 128]) torch.Size([16, 128]) torch.Size([16, 1]) print(train) print(mask) print(label) print(train.shape, mask.shape, label.shape) breakprint('len(train_dataloader)=', len(train_dataloader)) #368# 二分类结果评估def binary_acc(preds, labels): #preds.shape=(16, 2) labels.shape=torch.Size([16, 1]) # eq里面的两个参数的shape=torch.Size([16]) correct = torch.eq(torch.max(preds, dim=1)[1], labels.flatten()).float() if 0: print('binary acc ********') print('preds = ', preds) print('labels = ', labels) print('correct = ', correct) acc = correct.sum().item() / len(correct) return accimport timeimport datetime# 时间格式化def format_time(elapsed): elapsed_rounded = int(round((elapsed))) return str(datetime.timedelta(seconds=elapsed_rounded)) #返回 hh:mm:ss 形式的时间1.3.5 训练和评估1.3.5.1 加载预训练模型# 加载预训练模型, num_labels表示2个分类,好评和差评model = BertForSequenceClassification.from_pretrained("bert-base-chinese", num_labels = 2)# 使用GPUdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")model.to(device)1.3.5.2 定义优化器# 定义优化器 AdamW, eps默认就为1e-8(增加分母的数值,用来提高数值稳定性)no_decay = ['bias', 'LayerNorm.weight']optimizer_grouped_parameters = [ {'params': [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay)], 'weight_decay': WEIGHT_DECAY}, {'params': [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay)], 'weight_decay': 0.0}]optimizer = AdamW(optimizer_grouped_parameters, lr = LEARNING_RATE, eps = EPSILON)epochs = 2 #迭代次数# training steps 的数量: [number of batches] x [number of epochs].total_steps = len(train_dataloader) * epochs# 设计 learning rate scheduler.scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps = 0, num_training_steps = total_steps)1.3.5.3 定义模型训练# 定义模型训练def train(model, optimizer): t0 = time.time() # 记录当前时刻 avg_loss, avg_acc = [],[] # 开启训练模式 model.train() for step, batch in enumerate(train_dataloader): # 每隔40个batch 输出一下所用时间. if step % 40 == 0 and not step == 0: elapsed = format_time(time.time() - t0) print(' Batch {:>5,} of {:>5,}. Elapsed: {:}.'.format(step, len(train_dataloader), elapsed)) # 从batch中取数据,并放到GPU中 b_input_ids, b_input_mask, b_labels = batch[0].long().to(device), batch[1].long().to(device), batch[2].long().to(device) output = model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask, labels=b_labels) loss, logits = output[0], output[1] avg_loss.append(loss.item()) acc = binary_acc(logits, b_labels) avg_acc.append(acc) optimizer.zero_grad() loss.backward() clip_grad_norm_(model.parameters(), 1.0) optimizer.step() scheduler.step() avg_loss = np.array(avg_loss).mean() avg_acc = np.array(avg_acc).mean() return avg_loss, avg_acc1.3.5.4 训练 & 评估# 训练 & 评估for epoch in range(epochs): # 模型训练 train_loss, train_acc = train(model, optimizer) print('epoch={},train_acc={},loss={}'.format(epoch, train_acc, train_loss)) # 模型评估 test_acc = evaluate(model) print("epoch={},test_acc={}".format(epoch, test_acc))1.3.6 预测def predict(sen): # 将sen 转换为id input_id = convert_text_to_token(tokenizer, sen) # print(input_id) # 放到tensor中 input_token = torch.tensor(input_id).long().to(device) #torch.Size([128]) # 统计有id的部分,即为 1(mask),并且转换为float类型 atten_mask = [float(i>0) for i in input_id] # 将mask放到tensor中 attention_token = torch.tensor(atten_mask).long().to(device) #torch.Size([128]) # 转换格式 size= [1,128], torch.Size([128])->torch.Size([1, 128])否则会报错 attention_mask = attention_token.view(1, -1) output = model(input_token.view(1, -1), token_type_ids=None, attention_mask=attention_mask) return torch.max(output[0], dim=1)[1]label = predict('掏钱看这部电影,才是真正被杀猪盘了。。。')print('好评' if label==1 else '差评')label = predict('我觉得挺不错的。在中国看来算是最好的科幻大片了.毕竟国产。支持一下!')print('好评' if label==1 else '差评')label = predict('但是影片制作“略显”粗糙。包括但不限于演员演技拉胯,剧情尴尬,情节设计不合理。期待值最高的王千源完全像没睡醒,全片无论扮演什么身份或处于什么场景,表情就没变过。身体力行的告诉了我们,演员最重要不是演什么像什么,而是演什么就换什么衣服。除了人物身份的切换是靠换衣服外和张光北演对手戏完全就像是在看着提词器念台词,俩下对比尴尬到都能扣出个三室一厅。女配“陈茜”和“刘美美”一个没看到“孤身入虎穴”的作用在哪里,一个则是完全没必要出现。随着故事的递进加情节设计的不合理导致整片完全垮掉。或者你把俩女配的情节递进处理好了也行,但是很显然,导演完全不具备这种能力。不仅宏观叙事的能力差,主题把控的能力也欠缺。看似这个电影是宣传反诈,实则是披着反诈的外衣,上演了正派和反派间弱智般的“强强”对决。就以反诈题材来说做的都不如b站up主录制的几分缅北诈骗集团的小视频更有警示意义。我们搞反诈宣传的目的不就是为了避免群众上当受骗,同时告诉大家警惕国外高薪工作,不去从事诈骗活动吗?当然我要吐槽的包括但不限于以上这些,麻烦各位导演在拍偏主旋律电影的时候不要用类似于本片抓捕大boos时说的:“现在中国太强大了,怎么怎么地类似的台词了,把这份荣誉留给吴京吧!最后,本片唯一的亮点就是王迅和前三分之一节奏感还不错。哎,特价买的票以为我赚了,没想到是我被“杀猪盘了”。')print('好评' if label==1 else '差评')转载原文链接:【云驻共创】华为云AI之《情感专家》在线分析影评情感基调_云汉ai顾问 情感板块-CSDN博客
  • [技术干货] 华为云OCR服务
    1.简要介绍华为云OCR服务华为云文字识别主要分为:通用类、证件类、票据类、行业类、定制类。1.1 通用类OCR服务接口通用表格识别通用文字识别网络截图识别签名盖章检测手写数字字母识别OCR优势识别精度高,支持不同版面自适应分析自动化匹配信息,提升审核准确度提高效率,节约人工成本1.2 证件类OCR服务接口身份证识别行驶证识别驾驶证识别护照检测缅甸身份证识别OCR优势识别精度高,支持任意角度倾斜、缺角、反光、复杂背景等场景的卡证识别支持外语证件的订制OCR识别通过卡证识别,快速完成快递录单、手机开户等场景信息录入,实名认证1.3 票据类OCR服务接口增值税发票识别医疗发票识别机动车销售发票识别海关清关单据识别OCR优势支持多种票据自动识别,结构化提取多项关键信息支持图像翻转、文字错行、盖章干扰等复杂场景,数字、符号等文本识别精度高1.4 行业类OCR服务接口物流电子面单识别物流纸质面单识别医疗化验单据识别OCR优势行业解决方案成熟支持姓名、地址、电话等关键字段自动提取支持复杂背景、扭曲等情况1.5 定制类服务功能用户自定义模板,识别各类证件、票据专属API定制开发,满足高精度特殊场景OCR优势可视化界面操作,用户轻松指定识别区域,完成模板设计并调用服务接口对各类证件、票据定制独立模板,适应不同格式图片的自动识别及结构化提取2.华为云OCR服务的应用场景华为云OCR服务的应用场景主要有:身份验证场景物流快递场景2.1 身份验证场景在金融、证券、保险、政务、安防等众多领域中,大量场景需要对客户进行身份验证。本服务可审核证件是否为原件,有效防止照片翻拍、复印件翻拍、P图等欺骗行为,识别证件中的文字内容,并对接公安系统验证身份是否真实有效。2.2 物流快递场景物流快递场景用到OCR服务主要有两个方面:快递员取件填写运单、提取运单信息存入系统。物流快递场景主要流程如下:2.2.1 快递员取件填写运单1、身份证OCR:实名认证取件时,移动端APP:身份证拍照、识别、校验速度快:<1秒;精度高:>98%2、网络截图OCR电商收到买家地址截图、聊天截图OCR识别、自动提取信息(姓名、地址、电话等)快递员取件填写运单:华为云OCR能够准确识别不同角度、复杂背景图片,简化录入过程,提高服务效率。2.2.2 提取运单信息存入系统1、电子面单OCR自动提取:编号信息,收/寄件人姓名、电话、地址平均字符精度:99%2、纸质面单OCR文字检测:特定内容是否填写盖章检测:是否盖章(检视章),合规性检测等提取运单信息存入系统:华为云OCR能够智能处理各种复杂背景,提取结构化信息大幅节省人力,提升流程自动化程度。2.3 医疗保险理赔场景华为云OCR在医疗保险理赔场景中的优势主要有:加快理赔处理速度,明显提高用户体验,同时降低人保人工成本有效解决医疗单据中错行、文字相互覆盖、盖章干扰等复杂场景的文字识别;解决维吾尔文干扰的身份证文字识别2.4 汽车金融场景华为云OCR在汽车金融场景中的优势主要有:大幅提高数据录入核对效率,改善用户体验,同时降低人工成本提取购车发票等图片的结构化信息,有效解决旋转、错行、模糊变形等复杂场景,准确率高>98%自动进行合同签名检测,保证合规2.5 互联网网络截图场景互联网网络截图场景主要分为:电商图片、聊天截图。2.5.1 电商图片电商图片提取的主要信息主要有:店铺、商品主图,详情图用户评价图、打分订单编号、金额识别关注、收藏、心愿单截图华为云OCR在电商图片场景中的优势主要有:批量提取商品信息:价格、销量、评价等用户评价审核判断是否关注、收藏(淘宝返利)2.5.2 聊天截图电商图片提取的主要信息主要有:1、聊天截图聊天软件、社交网络截图聊天内容自动识别提取2、用户自生成(UGC)图片各种手机截图、网页截图用户拍照图片、合成图片华为云OCR在聊天截图场景中的优势主要有:快捷提取聊天信息:地址、电话等图像内容审查:敏感词检测信息统计、数据挖掘2.6 政法法院场景华为云OCR在政法法院场景中的优势主要有:支持各种格式文档、表格等图片识别,返回结构化文档大幅效率提升,准确率高,建立数据资产2.7 财务报销场景华为云OCR在财务报销场景中的优势主要有:支持方向检测,票据倾斜和扭曲矫正去除盖章影响2.8 医疗化验单/检验单OCR识别场景华为云OCR在医疗化验单/检验单OCR识别场中的优势主要有:自适应识别不同医院不同版式化验单自动提取姓名、年龄、住院号等关键信息支持扭曲变形、倾斜遮挡等复杂场景2.9 定制专属OCR服务接口:缅甸身份证OCR识别缅甸身份证OCR服务:支持缅甸文OCR识别适应任意角度倾斜、缺角、反光、复杂背景等场景,识别精度高定制专属OCR服务:满足不同版式个性化需求支持外语OCR识别专业团队快速定制开发在华为云上提供专属API接口3.华为云OCR服务定价3.1 按需付费、阶梯收费文字识别服务提供两种计费方式:按需付费、套餐包。用户可以根据实际需求变更资源的资费方式。套餐包价格相比“按需计费”具有更大折扣。API调用次数大时,套餐包更优惠。具体以官网实际价格为准:cid:link_03.2 专属定制如果需要专属定制OCR可以联系华为云客服进行咨询。官网:cid:link_0转载的原文链接:【云驻共创】华为云文字识别服务的体验之旅_华为云文字识别服务暂时只能支持中文和英文两种语言-CSDN博客
  • [技术干货] 华为云OCR使用指南
    1.华为云OCR SDK开发指南华为云SDK官网:cid:link_82.华为云OCR .NET SDK的使用2.1 前提准备进入密钥管理界面:cid:link_1点击确定后选择立即下载就可以获取Access Key(AK)和Secret Access Key(SK)。切换到API凭证,获取“IAM用户名”“、帐号名”以及待使用区域的“项目ID”。调用服务时会用到这些信息,请提前保存。2.2 安装对应语言的SDK使用SDK前,需要安装“HuaweiCloud.SDK.Core”和“HuaweiCloud.SDK.Ocr”,有两种安装方式,分别如下。使用 .NET CLI 工具dotnet add package HuaweiCloud.SDK.Coredotnet add package HuaweiCloud.SDK.Ocr使用 Package ManagerInstall-Package HuaweiCloud.SDK.CoreInstall-Package HuaweiCloud.SDK.Ocr2.3 开始使用2.3.1 导入依赖模块using HuaweiCloud.SDK.Core;using HuaweiCloud.SDK.Core.Auth;using HuaweiCloud.SDK.Ocr.V1;using HuaweiCloud.SDK.Ocr.V1.Model;2.3.2 配置客户端连接参数首先开通文字识别服务网址:cid:link_22.3.2.1 默认配置// 使用默认配置var config = HttpConfig.GetDefaultConfig();2.3.2.2 网络代理(可选)// 根据需要配置网络代理config.ProxyHost = "proxy.huaweicloud.com";config.ProxyPort = 8080;config.ProxyUsername = "test";config.ProxyPassword = "test";2.3.2.3 超时配置(可选)// 默认超时时间为120秒,可根据需要调整config.Timeout = 120;2.3.2.41 SSL配置(可选)// 根据需要配置是否跳过SSL证书验证config.IgnoreSslVerification = true;2.3.3 配置客户端连接参数配置AK、SK信息。华为云通过AK识别用户的身份,通过SK对请求数据进行签名验证,用于确保请求的机密性、完整性和请求者身份的正确性。//配置AK和SKconst string ak = "";const string sk = "";var auth = new BasicCredentials(ak,sk);2.3.4 初始化客户端2.3.4.1 指定云服务region方式(推荐)// 初始化指定云服务的客户端 {Service}Client ,以初始化OCR服务的 OcrClient 为例var client = OcrClient.NewBuilder() .WithCredential(auth) .WithRegion(OcrRegion.ValueOf("cn-north-4")) .WithHttpConfig(config) .Build();2.3.4.2 指定云服务endpoint方式// 指定终端节点,以OCR服务北京四的 endpoint 为例String endpoint = "https://ocr.cn-north-4.myhuaweicloud.com";// 初始化客户端认证信息,需要填写相应 projectId,以初始化 BasicCredentials 为例var auth = new BasicCredentials(ak, sk, projectId);// 初始化指定云服务的客户端 {Service}Client,以初始化OCR服务的 OcrClient 为例var client = OcrClient.NewBuilder() .WithCredential(auth) .WithEndPoint(endpoint) .WithHttpConfig(config) .Build();endpoint是华为云各服务应用区域和各服务的终端节点.2.3.5 发送请求并查看响应// 以调用通用表格识别接口 RecognizeGeneralTable 为例var req = new RecognizeGeneralTextRequest{};req.Body = new GeneralTextRequestBody(){ Url = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202005%2F23%2F20200523172615_reSrQ.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1655881933&t=52e3a855c74ac4096d5c7a5a721e9e6f"};try{ var resp = client.RecognizeGeneralText(req); var respStatusCode = resp.HttpStatusCode; Console.WriteLine(respStatusCode);}catch (Exception e){ Console.WriteLine(e);}2.3.6 异常处理一级分类一级分类说明二级分类二级分类说明ConnectionException连接类异常HostUnreachableException网络不可达、被拒绝。ConnectionException连接类异常SslHandShakeExceptionSSL认证异常。RequestTimeoutException响应超时异常CallTimeoutException单次请求,服务器处理超时未返回。RequestTimeoutException响应超时异常RetryOutageException在重试策略消耗完成后,仍无有效的响应。ServiceResponseException服务器响应异常ServerResponseException服务端内部错误,Http响应码:[500,]。ServiceResponseException服务器响应异常ClientRequestException请求参数不合法,Http响应码:[400,500)try{ var resp = client.RecognizeGeneralText(req); var respStatusCode = resp.HttpStatusCode; Console.WriteLine(respStatusCode);}catch (RequestTimeoutException requestTimeoutException){ Console.WriteLine(requestTimeoutException.ErrorMessage);}catch (ServiceResponseException clientRequestException){ Console.WriteLine(clientRequestException.HttpStatusCode); Console.WriteLine(clientRequestException.ErrorCode); Console.WriteLine(clientRequestException.ErrorMsg);}catch (ConnectionException connectionException){ Console.WriteLine(connectionException.ErrorMessage);}2.3.7 运行程序2.3.7.1 华为云在线调用2.3.7.1 代码调用github源码仓库地址:cid:link_4using HuaweiCloud.SDK.Core;using HuaweiCloud.SDK.Core.Auth;using HuaweiCloud.SDK.Ocr.V1;using HuaweiCloud.SDK.Ocr.V1.Model;//使用默认配置var config = HttpConfig.GetDefaultConfig();//配置AK和SKconst string ak = "DCZGIQS0WPHT9BJG5FNO";const string sk = "vE33MJGR2LC7uIrxNc8kznPNcNzjCtSbjTwxGEwb";//const string projectId = "0caad8f75980f3982f31c0016b5bd5ed";// 初始化客户端认证信息,需要填写相应 projectId,以初始化 BasicCredentials 为例var auth = new BasicCredentials(ak, sk);// 初始化指定云服务的客户端 {Service}Client ,以初始化OCR服务的 OcrClient 为例var client = OcrClient.NewBuilder() .WithCredential(auth) .WithRegion(OcrRegion.ValueOf("cn-north-4")) .WithHttpConfig(config) .Build();// 以调用通用表格识别接口 RecognizeGeneralTable 为例var req = new RecognizeGeneralTextRequest{};req.Body = new GeneralTextRequestBody(){ Url = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202005%2F23%2F20200523172615_reSrQ.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1655881933&t=52e3a855c74ac4096d5c7a5a721e9e6f"};try{ var resp = client.RecognizeGeneralText(req); var respStatusCode = resp.HttpStatusCode; Console.WriteLine(respStatusCode);}catch (RequestTimeoutException requestTimeoutException){ Console.WriteLine(requestTimeoutException.ErrorMessage);}catch (ServiceResponseException clientRequestException){ Console.WriteLine(clientRequestException.HttpStatusCode); Console.WriteLine(clientRequestException.ErrorCode); Console.WriteLine(clientRequestException.ErrorMsg);}catch (ConnectionException connectionException){ Console.WriteLine(connectionException.ErrorMessage);}// See https://aka.ms/new-console-template for more informationConsole.WriteLine("Hello, World!");3.华为云OCR SDK的相关参考华为云OCR SDK参考文档:cid:link_3华为云OCR API参考文档:cid:link_52.华为云文字识别OCR服务操作指南2.1 选择华为云文字识别OCR服务的理由华为云文字识别OCR服务主要优势有以下几点:优势1:识别精度高采用先进的深度学习算法,针对各种业务场景优化,文字识别精度高优势2:稳定服务成功应用于各类场景,基于华为等企业客户的长期实践,经受过复杂场景考验优势3:支持复杂场景证件支持复杂背景、扭曲、倾斜;表单支持盖章、错行等场景优势4:简单易用提供符合RESTful规范的API访问接口,兼容性强,使用方便2.2 华为云文字识别Console介绍华为云OCR服务官网:cid:link_92.2.1 进入Console页面2.2.1.1 申请服务在“文字识别”控制台的“商用服务”页签中可以申请服务,确保申请服务成功的前提是账号已经通过实名验证。找到文字识别OCR进入页面点击立即使用进入控制台在当前的服务申请页面中可以通过“了解更多”了解该服务支持的场景表,同时建议申请服务前通过“了解计费详情”了解每个服务的计费标准,目前OCR服务计费项是根据每个服务API成功调用的次数进行阶梯计费(调用量越大单次调用的费用越低),调用API的方式有两种:TokenAK/SKToken及AK/SK获取方式请参考以下链接:http://forum.huaweicloud.com/forum.php?mod=viewthread&tid=5028&page=1&extra=#pid60432.2.1.2 服务支持场景及API调用计费标准场景说明身份证识别自动识别身份证上的全部信息,支持身份证正反面识别,一次扫描即可识别身份证号码、姓名、地址等全部信息,在暗光、倾斜、过曝光、阴影等异常条件下均可准确识别身份证信息驾驶证识别自动识别驾驶证正页上的全部信息,自动提取出姓名、性别、领证日期、准驾车型、有效期限等结构化信息,在暗光、倾斜、过曝光、防伪标志干扰、阴影等异常条件下均可准确识别驾驶证信息行驶证识别自动识别行驶证正页上的全部信息,自动提取出号牌号码、车辆类型、所有人、使用性质、品牌型号、车辆识别代号、发动机号码、注册日期等结构化信息,在暗光、倾斜、过曝光、防伪标志干扰、阴影等异常条件下均可准确识别行驶证信增值税发票识别通过对增值税发票图片预处理、表格提取、文字提取、文字识别、结构化信息输出等一系列技术化手段,快速将增值税发票上的文字信息识别出来,用于后续的进一步处理,节省大量的人工录入成本英文海关单据识别可识别出英文海关单据图片上的文字内容和数字,智能提取为可编辑的文本。英文海关单据识别采用了自动定位分割算法、分布式计算框架、集成深度学习进行纠错,经过大规模图像文字训练,达到高精度的识别要通用表格识别提取表格内的文字和所在行列位置信息,适应不同格式的表格。同时也识别表格外部的文字区域。用于各种单据和报表的电子化,恢复结构化信息通用文字识别提取图片内的文字及其对应位置信息,并能够根据文字在图片中的位置进行结构化整理工作手写字母数字识别提取表格内的手写字母、数字和所在行列位置信息,适应不同格式的表格。同时也支持表格外部文字区域的手写字母数字识别机动车销售发票识别自动识别机动车销售发票图片内的文本内容,并返回结构化字段信息,用于后续的进一步处理,节省大量的人工录入成本更多价格详情:cid:link_7总结文字识别应用的场景非常的广,基本上所有用到文字的领域都需要文字识别。比如说是物流与制造业,金融保险,医疗教育,政务政法,互联网等,我们的产品基本上在这几个方面都有应用。华为云文字识别服务有如下的特点,首先的识别精度高,证件和票据类的识别率在很多场景都能达到99%以上,数据安全和端云协同前面已经提过了。我们还有高适应性,比如说支持错行、盖章、倾斜、文字叠加、反光、任意角度等复杂场景,同时多种易用的SDK。很多时候你的产品再好,不好用,消费者也是不认可的。最后就是高可用,基本上可以支持每月十亿级或者更高的调用量。本文主要介绍了华为云文字识别服务的相关概念和使用实操,想使用华为云OCR服务的小伙伴可以执行实操流程步骤来实现自己业务场景。原文链接:【云驻共创】华为云文字识别服务的体验之旅_华为云文字识别服务暂时只能支持中文和英文两种语言-CSDN博客
  • [技术干货] 初识OCR技术
    1.文字识别技术的概念1.1 文字识别(OCR)介绍文字识别:光学字符识别(Optical Character Recognition,OCR)是指对文本资料的图像文件进行分析识别处理,获取文字及版面信息的过程。OCR以开放API(Application Programming Interface,应用程序编程接口)的方式提供给用户,用户使用Python、Java等编程语言调用OCR服务API将图片识别成文字,帮助用户自动采集关键数据,打造智能化业务系统,提升业务效率。1.2 文字识别(OCR)应用场景华为云OCR使用要求用户需要具备编程能力,熟悉Java/Python/iOS/Android/Node.js编程语言。服务需要用户通过调用API接口,实现将图片或扫描件中的文字识别成可编辑的文本。文字提取之后返回的结果是JSON格式,用户需要通过编码将识别结果对接到业务系统或保存为TXT、Excel等格式。文字识别(OCR)应用场景主要有以下三个方面:类型说明通用类OCR(General OCR)支持表格识别、文档识别、网络图片识别、手写文字识别、智能分类识别、健康码识别、核酸检测记录识别等任意格式图片上文字信息的自动化识别,自适应分析各种版面和表格,快速实现各种文档电子化。票据类OCR(Receipt OCR)支持增值税发票识别、机动车销售发票识别、出租车发票识别、火车票识别、定额发票识别、车辆通行费发票识别、飞机行程单识别以及发票验真;支持图片及PDF、OFD文档上有效信息的自动识别和结构化提取。证件类OCR(Card OCR)支持身份证识别、行驶证识别、驾驶证识别、护照识别、营业执照识别、银行卡识别、道路运输证识别、车牌识别、名片识别、VIN码识别、道路运输从业资格证识别等卡证图片上有效信息的自动识别和关键字段结构化提取。2.文字识别技术的发展历程2.1 OCR识别领域发展历程OCR识别领域发展历程主要经历以下几个历程:西文OCR=》Tesseract=》LeNet=》深度学习OCR2.1.1 西文OCR在OCR技术中,印刷体文字识别是开展最早,技术上最为成熟的一个。欧美国家为了将浩如烟海、与日俱增的大量报刊杂志、文件资料和单据报表等文字材料输入计算机进行信息处理,从上世纪50年代就开始了西文OCR技术的研究,以便代替人工键盘输入。经过40多年的不断发展和完善,并随着计算机技术的飞速发展,西文OCR技术现已广泛应用于各个领域,使得大量的文字资料能够快速、方便、省时省力和及时地输入到计算机中,实现了信息处理的“电子化”。2.1.1 TesseractTesseract的OCR引擎最先由HP实验室于1985年开始研发,至1995年时已经成为OCR业内最准确的三款识别引擎之一。然而,HP不久便决定放弃OCR业务,Tesseract也从此尘封。数年以后,HP意识到,与其将Tesseract束之高阁,不如贡献给开源软件业,让其重焕新生。2005年,Tesseract由美国内华达州信息技术研究所获得,并求诸于Google对Tesseract进行改进、消除Bug、优化工作。Tesseract目前已作为开源项目发布在Google Project,其最新版本3.0已经支持中文OCR,并提供了一个命令行工具。2.1.3 LeNetLeNet是经典CNN(Convolutional Neural Network)神经网络构造之一,第一次是在1995年由Yann LeCun,Leon Bottou,Yoshua Bengio,和Patrick Haffner提出的,这种神经网络结构在MINIST手写数字数据集上取得了优异的结果。下面是使用LeNet进行识别的过程:安排数据确定超参数建立网络结构,写上损失函数和优化器安排训练过程安排测试过程保存模型# coding=utf-8 (在源码开头声明编码方式,这样注释和代码中有中文不会报错)import torch # 导入pytorch库import torch.nn as nn # torch.nn库import torch.nn.functional as Fimport torch.optim as optim#torch.optim包主要包含了用来更新参数的优化算法,比如SGD、AdaGrad,RMSProp、 Adam等from torchvision import datasets, transforms#torchvision包含关于图像操作的方便工具库。# vision.datasets:几个常用的数据库,可以下载和加载;#vision.models:流行的模型,比如AlexNet,VGG,ResNet等#vision.transforms:常用的图像操作,例如:随机切割,旋转,数据类型转换,图像转到tensor,tensor到图像等。#vision.utils: 用于把形似 (3 x H x W) 的张量保存到硬盘中,给一个mini-batch的图像可以产生一个图像格网。from torch.autograd import Variable#torch.autograd.Variable是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现from torch.utils.data import DataLoader#PyTorch中数据读取的一个重要接口是torch.utils.data.DataLoader,该接口定义在dataloader.py脚本中,只要是用PyTorch来训练模型基本都会用到该接口,该接口主要用来将自定义的数据读取接口的输出或者PyTorch已有的数据读取接口的输入按照batch size封装成Tensor,后续只需要再包装成Variable即可作为模型的输入# 下载训练集。在pytorch下可以直接调用torchvision.datasets里面的MNIST数据集(这是官方写好的数据集类),这是方法一。还可以自己定义和加载。加载之后的train_dataset等于train_dataset = datasets.MNIST(root='./num/', train=True, transform=transforms.ToTensor(), download=True)#root(string): 数据集的根目录root directory。'./num/'意思就是建立在根目录下建立一个num文件夹,把num下的MNIST数据集加载进来。#train是可选填的,表示从train.pt创建数据集,就是进入训练数据集开启训练模式。#transform是选填的,接收PIL图像并且返回已转换版本。#download也是选填的,如果true就从网上下载数据集并放在根目录/num下,如果已经下载好了就不会再次下载。# 下载测试集test_dataset = datasets.MNIST(root='./num/', train=False, transform=transforms.ToTensor(), download=True)# dataset 参数用于指定我们载入的数据集名称# 在装载的过程会将数据随机打乱顺序并进打包batch_size = 64# batch_size参数设置了每个包中的图片数据个数# 装载训练集train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)#建立一个数据迭代器,在训练模型时使用到此函数,用来把训练数据分成多个小组,此函数每次抛出一组数据。直至把所有的数据都抛出。就是做一个数据的初始化。#dataset——给出需要加载的数据来源,train_dataset的类型是torchvision.datasets.mnist.MNIST#batchsize——选填,一次加载多少个数据样本,默认是1个#shuffle——选填,true就是每个epoch都会洗一下牌,默认是不洗牌# 装载测试集test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=True)#建立网络结构# 卷积层使用 torch.nn.Conv2d# 激活层使用 torch.nn.ReLU# 池化层使用 torch.nn.MaxPool2d# 全连接层使用 torch.nn.Linearclass LeNet(nn.Module):#LeNet类是从torch.nn.Module这个父类继承下来的,在__init__构造函数中申明各个层的定义,然后再写上forward函数,在forward里定义层与层之间的连接关系,这样就完成了前向传播的过程。 def __init__(self): super(LeNet, self).__init__()#super(LeNet,self)__init__():在单继承中 super 主要是用来调用父类的方法的,而且在python3中可以 用super().xxx 代替 super(Class, self).xxx self.conv1 = nn.Sequential(nn.Conv2d(1, 6, 3, 1, 2), nn.ReLU(), nn.MaxPool2d(2, 2))#nn.Sequential是一个顺序容器,将神经网络模块按照传入顺序依次被添加到计算图中执行。#Conv2D的结构是:nn.Conv2d(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)) self.conv2 = nn.Sequential(nn.Conv2d(6, 16, 5), nn.ReLU(), nn.MaxPool2d(2, 2)) self.fc1 = nn.Sequential(nn.Linear(16 * 5 * 5, 120), nn.BatchNorm1d(120), nn.ReLU()) self.fc2 = nn.Sequential( nn.Linear(120, 84), nn.BatchNorm1d(84), nn.ReLU(), nn.Linear(84, 10)) # 最后的结果一定要变为 10,因为数字的选项是 0 ~ 9 def forward(self, x): x = self.conv1(x) x = self.conv2(x) x = x.view(x.size()[0], -1) #x.view(x.size(0), -1)这句话是说将第二次卷积的输出拉伸为一行,接下来就是全连接层 x = self.fc1(x) x = self.fc2(x) return x#指定设备。“cuda:0”代表起始的device_id为0,如果直接是“cuda”,同样默认是从0开始。可以根据实际需要修改起始位置,如“cuda:1”。device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')LR = 0.001#LR是学习率,这是一个超参数#实例化LeNet。to(device)代表将模型加载到指定设备上。net = LeNet().to(device)# 损失函数使用交叉熵criterion = nn.CrossEntropyLoss()# 优化函数使用 Adam 自适应优化算法optimizer = optim.Adam( net.parameters(), lr=LR,)epoch = 1if __name__ == '__main__': #如果这个脚本是主函数,那么就运行如下代码。“__name__”是Python的内置变量,用于指代当前模块。 for epoch in range(epoch): sum_loss = 0.0 for i, data in enumerate(train_loader): #enumerate()用于可迭代\可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标。data里面包含图像数据(inputs)(tensor类型的)和标签(labels)(tensor类型) inputs, labels = data inputs, labels = Variable(inputs).cuda(), Variable(labels).cuda() #注意使用多gpu时训练或测试 inputs和labels需加载到gpu中。模型和相应的数据进行.cuda()处理。就可以将内存中的数据复制到GPU的显存中去 optimizer.zero_grad() #每个batch开始时都需要将梯度归零 outputs = net(inputs) #将数据传入网络进行前向运算 loss = criterion(outputs, labels) #得到损失函数 loss.backward() #反向传播 optimizer.step() #通过梯度做一步参数更新 # print(loss) sum_loss += loss.item() #pytorch中,.item()方法 是得到一个元素张量里面的元素值#具体就是 用于将一个零维张量转换成浮点数,比如计算loss,accuracy的值 if i % 100 == 99: print('[%d,%d] loss:%.03f' % (epoch + 1, i + 1, sum_loss / 100)) sum_loss = 0.0net.eval() #将模型变换为测试模式#在PyTorch中进行validation时,会使用model.eval()切换到测试模式,在该模式下,主要用于通知dropout层和batchnorm层在train和val模式间切换。#在train模式下,dropout网络层会按照设定的参数p设置保留激活单元的概率(保留概率=p); batchnorm层会继续计算数据的mean和var等参数并更新。#在val模式下,dropout层会让所有的激活单元都通过,而batchnorm层会停止计算和更新mean和var,直接使用在训练阶段已经学出的mean和var值。该模式不会影响各层的gradient计算行为,即gradient计算和存储与training模式一样,只是不进行backprobagation。correct = 0total = 0for data_test in test_loader: images, labels = data_test images, labels = Variable(images).cuda(), Variable(labels).cuda() output_test = net(images) _, predicted = torch.max(output_test, 1) #其中这个 1代表行,0的话代表列。#不加_,返回的是一行中最大的数。#加_,则返回一行中最大数的位置。 total += labels.size(0) correct += (predicted == labels).sum() print("correct1: ", correct) print("Test acc: {0}".format(correct.item() / len(test_dataset)))2.1.4 深度学习OCR随着深度学习OCR发展,MINST数据集的建立开始使用各种深度学习算法,OCR也广泛进入了商业化领域。进入20世纪90年代以后,随着平台式扫描仪的广泛应用,以及我国信息自动化和办公自动化的普及,大大推动了OCR技术的进一步发展,使OCR的识别正确率、识别速度满足了广大用户的要求。其中以OCR为科技核心的云脉技术不断创新进取,研发了一系列OCR软件产品,并且运用在医院,学校,企业等各大市场。2.2 OCR识别流程历程下面是经典的光学字符识别系统流程和技术框架图解:下面是基于CNN-RNN的序列光学字符识别流程图解:目前,在OCR文字定位与识别领域,主流方法都是基于深度学习方法。如在ICDAR2013自然场景上前20名已经见不到传统方法的影子了。3.简要介绍文字定位与文字识别技术目前OCR技术主要分为文字定位和文字识别两个流程。3.1 文字定位文字定位是文字识别的前提条件,要解决的问题是如何在杂乱无序、千奇百怪的不同场景中准确地定位出文字的位置。由于不同场景背景的复杂性、光照的多变性以及字体的不可预测性等原因,文字定位面临着极大的挑战。文字定位主要有传统方法和深度学习两种:基于传统方法、基于深度学习。3.1 基于传统方法传统方法:人工设计特征描述,基于模板匹配方式识别文字,需要准确的特征描述,难以满足复杂场景识别任务。基于连通区域(MSER,SWT…)基于滑动窗3.2 基于深度学习深度学习方法:海量标注数据自动学习文字特征,主流方法是基于CNN+RNN的深度学习网络。3.2.1 基于侯选框TextBoxes:A fast text detector with a single deep neural networkDetecting Oriented Text in Natural Images by Linking Segments3.2.2 基于分割Multi-oriented text detection with fully convolutional networks3.2.3 直接回归Deep Direct Regression for Multi-Oriented Scene Text Detection原文链接:【云驻共创】华为云文字识别服务的体验之旅_华为云文字识别服务暂时只能支持中文和英文两种语言-CSDN博客
  • [技术干货] ModelArts Pro情感分析工作流【转载】
    1.ModelArts Pro是什么ModelArts Pro 是为企业级AI应用打造的专业开发套件。基于华为云的先进算法和快速训练能力,提供预置工作流和模型,提升企业AI应用的开发效率,降低开发难度。同时,支持客户自主进行工作流编排,快速实现应用的开发、共享和发布,共建开放生态,实现普惠行业AI落地。华为云全球首发企业级AI 应用开发套件 ModelArts Pro,加速行业AI 落地ModelArts Pro将算法专家的积累和行业专家的知识沉淀在相应的套件和“行业工作流”(Workflow)中,实现AI能力的复用。自然语言套件帮助文档:cid:link_12.ModelArts Pro的前提准备登录ModelArts Pro平台:cid:link_2模型训练选择自然语言处理套件3. ModelArts Pro的使用1、情感分析工作流,新建应用2、填写相关信息点击确定3、创建数据集,构建标注工作数据集主要有数据选择=》模型训练=》模型评估=》服务部署4、数据选择界面如图5、模型训练过程可以看到训练详情6、训练完成后,进行模型评估7、在线部署8、推理测试总结本文着重介绍了:Word Embedding、BERT原理、Transformer原理、Project:BERT中文电影评论正负情感分析、使用ModelArts Pro快速上手自定义主题情感分析。本文一步步实操了电影评论正负情感分析流程,明白了电影评论是分析情感是如何处理的,了解了很多相关的概念的知识,收获满满。而ModelArts Pro提供完整的工作流应用可以快速部署成API服务,满足实际业务的需求。转载原文为:【云驻共创】华为云AI之《情感专家》在线分析影评情感基调_云汉ai顾问 情感板块-CSDN博客
  • [技术干货] ModelBox搭建的AI寻车系统
    1.案例效果本案例主要使用的技术有:FairMOT进行车辆检测与跟踪yolov5进行车牌检测crnn进行车牌识别,在停车场入口、出口、停车位对车辆进行跟踪与车牌识别,无论停车场路线多复杂,小车在你掌控之中最终效果如下:2.环境安装2.1 ModelBox端云协同AI开发套件(Windows)设备注册2.1.1 安装VS Code与使用ModelBox的其他套件一样,我们推荐使用VS Code进行技能开发,请登录VS Code官网下载安装Windows x64版本的编辑器。2.1.2 注册HiLens设备HiLens设备的注册有两种方式:使用VS Code插件注册登录华为云HiLens页面手动下载注册固件,使用命令行注册。 我们推荐第一种方式,操作更简单1)在VS Code中搜索并安装ModelBox管理插件:2)安装完成后,点击界面下方进入华为云登录界面,获取访问密钥,再进行登录:如果有访问密钥,即AK/SK,直接输入登录即可登录;否则则需要点击第②步获取访问密钥,在弹出的页面点击新增访问密钥,确认后将下载的表格文件中的AK/SK依次复制填入第③步的填空框内即可。3)如下图依次点击,进行ModelBox设备注册:4)确认后,如下图显示“运行中”即完成注册:2.2 ModelBox端云协同AI开发套件(Windows)SDK安装2.2.1 安装Git for WindowsModelBox中有些脚本的执行依赖bash,使用Git bash也可以让开发者在Windows上获得与Linux相同的执行环境,因此需要安装Git for Windows。安装完成后右键点击可以看到:2.2.2 下载ModelBox sdk1)在HiLens管理控制台专业版的技能开发-工具/插件板块下载Windows系列的ModelBox sdk:2)新建一个用于ModelBox开发的文件夹(注意路径中不能有中文和空格),将下载的sdk压缩包移动到该路径并解压,使用VS Code打开该文件夹:其中modelbox-win10-x64文件夹即为ModelBox核心库,包含ModelBox运行环境、内置的功能单元等。另外,为了做到开箱即用,可以看到sdk中已经包含了Python运行环境(python-embed目录),AI应用常用的OpenCV、NumPy等三方库也已经内置,开发者无需手动安装。此外,我们也推荐安装一些VS Code插件,提高开发效率。1、Python插件后面教程会涉及到ModelBox的Python功能单元开发,推荐安装Python插件,微软官方出品,可以进行语法高亮、自动补全、代码跳转等:2、Even Better TOMLModelBox中的流程图、配置文件等使用 TOML 语法编写,因此我们推荐安装 Even Better TOML 插件,可以进行语法检查、关键字高亮、文件排版等:3)打开Terminal终端4)ModelBox技能模板我们准备了一些口罩检测、手势检测、人体姿态识别等AI技能模板,存放在华为云OBS中;然后在ModelBox sdk中提供了一个solution.bat工具,用于下载云侧的技能模板,执行.\solution.bat -l可看到当前已有的技能模板:3.AI寻车系统搭建相关步骤这个应用对应的ModelBox版本已经做成模板放在华为云OBS中,可以用sdk中的solution.bat工具下载,接下来我们给出该应用在ModelBox中的完整开发过程:3.1 下载模板执行.\solution.bat -l可看到当前公开的技能模板:结果中的vehicle_plate_multi_centernet_yolov5_crnn即为AI寻车应用模板,可使用如下命令下载模板:.\solution.bat -s vehicle_plate_multi_centernet_yolov5_crnnsolution.bat工具的参数中,-l 代表list,即列出当前已有的模板名称;-s 代表solution-name,即下载对应名称的模板。下载下来的模板资源,将存放在ModelBox核心库的solution目录下。3.2 创建工程在ModelBox sdk目录下使用create.bat创建vehicle_plate工程:.\create.bat -t server -n vehicle_plate -s vehicle_plate_multi_centernet_yolov5_crnncreate.bat工具的参数中,-t 表示创建事务的类别,包括工程(server)、Python功能单元(Python)、推理功能单元(infer)等;-n 代表name,即创建事务的名称;-s 代表solution-name,表示将使用后面参数值代表的模板创建工程,而不是创建空的工程。workspace目录下将创建出vehicle_plate工程,工程内容如下所示:vehicle_plate|--bin│ |--main.bat:应用执行入口│ |--mock_task.toml:应用在本地执行时的输入输出配置,此应用默认使用4路本地视频文件为输入源,最终结果拼接为四宫格输出到屏幕,可根据需要修改|--CMake:存放一些自定义CMake函数|--data:存放应用运行所需要的图片、视频、文本、配置等数据│ |--chuchang_10.mp4:停车场出口测试视频│ |--ruchang_10.mp4:停车场入口测试视频│ |--ruku_10.mp4:停车位1测试视频│ |--kong_10.mp4:停车位2测试视频│ |--plate_keys.txt:车牌字符文件│ |--content_file.json:技能参数全局配置文件|--dependence│ |--modelbox_requirements.txt:应用运行依赖的外部库在此文件定义,本应用依赖pillow、scipy等工具包|--etc│ |--flowunit:应用所需的功能单元存放在此目录│ │ |--cpp:存放C++功能单元编译后的动态链接库,此应用没有C++功能单元│ │ |--collapse_ocr:归拢功能单元,车牌识别后处理│ │ |--condition:条件功能单元,判断是否检测到车辆/车牌│ │ |--draw_full_screen:多路视频拼接输出功能单元│ │ |--draw_plate:车牌检测结果绘制│ │ |--draw_track_bbox:车辆跟踪结果绘制│ │ |--expand_image:展开功能单元,展开车辆检测/车牌检测结果并行推理│ │ |--letter_resize:车辆检测预处理功能单元│ │ |--object_tracker:跟踪功能单元│ │ |--plate_det_post:车牌检测后处理功能单元│ │ |--url_cfg:流单元,多路输入解析│ │ |--vehicle_det_post:车牌检测结果绘制|--flowunit_cpp:存放C++功能单元的源代码,此应用没有C++功能单元|--graph:存放流程图│ |--vehicle_plate.toml:默认流程图,使用本地视频文件作为输入源│ |--modelbox.conf:modelbox相关配置|--hilens_data_dir:存放应用输出的结果文件、日志、性能统计信息|--model:推理功能单元目录│ |--vehicle_det:车辆检测推理功能单元│ │ |--vehicle_det.toml:车辆检测推理功能单元的配置文件│ │ |--vehicle_det_320x576.onnx:车辆检测onnx模型│ |--plate_det:车牌检测推理功能单元│ │ |--plate_det.toml:车牌检测推理功能单元的配置文件│ │ |--plate_det.onnx:车牌检测onnx模型│ |--plate_rec:车牌识别推理功能单元│ │ |--plate_rec.toml:车牌识别推理功能单元的配置文件│ │ |--plate_rec.onnx:车牌识别onnx模型|--build_project.sh:应用构建脚本|--CMakeLists.txt|--rpm:打包rpm时生成的目录,将存放rpm包所需数据|--rpm_copyothers.sh:rpm打包时的辅助脚本3.3 查看流程图vehicle_plate工程graph目录下存放流程图,默认的流程图vehicle_plate.toml与工程同名,其内容为(以Windows版ModelBox为例):anar_transpose device=cpu deviceid="0"] plate_normalize[type=flowunit flowunit=normalize device=cpu deviceid=0 standard_deviation_inverse="0.003921568627451,0.003921568627451,0.003921568627451"] plate_det[type=flowunit flowunit=plate_det device=cpu deviceid="0", batch_size=1] plate_det_post[type=flowunit, flowunit=plate_det_post, device=cpu, deviceid=0] plate_condition[type=flowunit, flowunit=condition, device=cpu, deviceid=0, key="plate"] expand_plate[type=flowunit, flowunit=expand_image, device=cpu, deviceid=0, img_h=48, img_w=168, key="plate"] ocr_color_transpose[type=flowunit flowunit=packed_planar_transpose device=cpu deviceid="0"] ocr_mean[type=flowunit flowunit=mean device=cpu deviceid="0" mean="149.94,149.94,149.94"] ocr_normalize[type=flowunit flowunit=normalize device=cpu deviceid=0 standard_deviation_inverse="0.020319,0.020319,0.020319"] plate_rec[type=flowunit flowunit=plate_rec device=cpu deviceid="0", batch_size=1] collapse_ocr[type=flowunit flowunit=collapse_ocr device=cpu deviceid="0"] draw_plate[type=flowunit, flowunit=draw_plate, device=cpu, deviceid=0] draw_track_bbox[type=flowunit, flowunit=draw_track_bbox, device=cpu, deviceid=0] draw_full_screen[type=flowunit, flowunit=draw_full_screen, device=cpu, deviceid=0] video_out[type=flowunit, flowunit=video_out, device=cpu, deviceid=0, full_screen=true] input1:input -> data_source_parser:in_data data_source_parser:out_video_url -> url_cfg:in_1 url_cfg:out_1 -> video_demuxer:in_video_url video_demuxer:out_video_packet -> video_decoder:in_video_packet video_decoder:out_video_frame -> letter_resize:in_image letter_resize:resized_image -> color_transpose:in_image color_transpose:out_image -> normalize:in_data normalize:out_data -> vehicle_det:input vehicle_det:output -> vehicle_det_post:in_feat letter_resize:out_image -> vehicle_det_post:in_image vehicle_det_post:out_feat -> object_tracker:in_feat object_tracker:out_track -> vehicle_condition:in_track video_decoder:out_video_frame -> vehicle_condition:in_image vehicle_condition:out_track -> expand_car:in_image expand_car:out_image -> plate_color_transpose:in_image plate_color_transpose:out_image -> plate_normalize:in_data plate_normalize:out_data -> plate_det:input plate_det:output -> plate_det_post:in_feat expand_car:out_image -> plate_det_post:in_image plate_det_post:out_tracks -> plate_condition: in_track vehicle_condition:out_track -> plate_condition: in_image plate_condition:out_track -> expand_plate:in_image expand_plate:out_image -> ocr_color_transpose:in_image ocr_color_transpose:out_image -> ocr_mean:in_data ocr_mean:out_data -> ocr_normalize:in_data ocr_normalize:out_data -> plate_rec:input plate_rec:output -> collapse_ocr:in_feat expand_plate:out_image -> collapse_ocr:in_image collapse_ocr:out_tracks -> draw_plate:in_feat plate_condition:out_track -> draw_plate:in_image draw_plate:out_image -> draw_track_bbox:in_image plate_condition:out_image -> draw_track_bbox:in_image draw_track_bbox:out_image -> draw_full_screen:in_image vehicle_condition:out_image -> draw_full_screen:in_image draw_full_screen:out_image -> video_out:in_video_frame}"""[flow]desc = "vehicle_plate run in modelbox-win10-x64"将流程图可视化:功能解释如下:灰色部分为预置功能单元绿色为一般通用功能单元红色为推理功能单元蓝色为条件功能单元黄色为展开归拢功能单元整个应用逻辑如下:视频解码后做图像预处理接着是车辆检测模型后处理得到车形框与128维车辆reid特征送入跟踪算法进行实时跟踪,经过条件功能单元判断,检测到车辆的图送入展开功能单元切图进行车牌检测,车牌检测结果归拢后同样要判断是否检测到车牌检测到车牌的帧再展开并行进行车牌识别,未检测到的则直接绘制车辆信息。 而未检测到车辆的帧则直接送入多路拼接功能单元,最终输出。3.4 核心逻辑本应用核心逻辑中的跟踪与区域判断,跟踪逻辑在object_tracker功能单元中,检测与跟踪使用的是FairMOT算法,算法介绍可参考论文。首先查看object_tracker功能单元中返回的跟踪对象结构:def get_tracking_objects(self, online_targets_dict): tracking_objects = {} for cls_id in range(self.num_classes): online_targets = online_targets_dict[cls_id] for t in online_targets: obj = {} tlwh = t.tlwh if tlwh[2] * tlwh[3] < self.min_box_area: continue tid = t.track_id obj["bbox"] = [max(0, tlwh[0]), max(0, tlwh[1]), tlwh[0] + tlwh[2], tlwh[1] + tlwh[3]] obj["licence"] = "" obj["licence_score"] = 0.0 obj["plate"] = np.zeros((4, 2)).tolist() obj["plate_score"] = 0.0 obj["bbox_score"] = t.score tracking_objects[tid] = obj return tracking_objects可以看到,我们返回的跟踪对象包括车型框、车辆检测得分等已有信息以及车牌、车牌得分、车牌框、车牌框得分等包含默认数据的占位信息,方便后续功能单元获取更新。从流程图中可以看到,object_tracker后结果送入车辆检测条件功能单元,同样的在流程图中还包含车牌检测条件功能单元,我们当然是希望使用同一个功能单元完成两个判断,所以在条件功能单元condition中,我们配置了参数key,默认为key = “bbox”,即对结构体中的车型框进行判断,具体实现为:if track_result and np.any([v.get(self.key) for k, v in track_result.items()]): buffer_img.set("track", track_json) out_track.push_back(buffer_img)else: buffer_img.set("track", track_json) out_image.push_back(buffer_img)这样的话如果是对车型框进行判断,只需要在流程图中配置key = “plate”即可。同样的,图展开功能单元expand_image也使用了同样的方法,使车辆检测与车牌检测可以共用功能单元:tracking_objects = json.loads(buffer_img.get("track"))for idx, target in tracking_objects.items(): box = np.array(target.get(self.key)) ...此外,由于本应用输入为4路视频,因此需要在url_cfg单元中进行session级别信息配置:url_str = str(self.count) + input_meta.get_private_string("source_url") self.count += 1data_context.get_session_context().set_private_string("multi_source_url", url_str)session级别的信息在功能单元之间是同步的,这样就可以在后续的功能单元中获取当前输入为哪路输入:url = data_context.get_session_context().get_private_string("multi_source_url")image_index = int(url[0])同样的,对于多路输入,我们需要在本地mock时在bin/mock_task.toml文件中进行输入配置:[input]type = "url"url = "${HILENS_APP_ROOT}/data/ruchang_10.mp4"[input1]type = "url"url = "${HILENS_APP_ROOT}/data/chuchang_10.mp4"[input2]type = "url"url = "${HILENS_APP_ROOT}/data/ruku_10.mp4"[input3]type = "url"url = "${HILENS_APP_ROOT}/data/kong_10.mp4"对于多路输入的感兴趣区域划定,我们使用content_file配置:[common]content_file = "../data/content_file.json"配置文件内容为:[ { "vehicle_area": "190,245,382,656,1265,630,956,249", "plate_area": "190,245,382,656,1265,630,956,249" }, { "vehicle_area": "663,467,228,675,994,682,1167,459", "plate_area": "663,467,228,675,994,682,1167,459" }, { "vehicle_area": "0,0,1280,0,1280,720,0,720", "plate_area": "0,0,1280,0,1280,720,0,720" }, { "vehicle_area": "0,0,1280,0,1280,720,0,720", "plate_area": "0,0,1280,0,1280,720,0,720" }]即针对不同输入配置各自的车型车牌感兴趣区域,在后续功能单元中获取配置的参数信息进行处理,如plate_det_post功能单元:self.areas = json.loads(data_context.get_session_config().get_string("iva_task_common"))url = data_context.get_session_context().get_private_string("multi_source_url")image_index = int(url[0])self.area = self.areas[image_index].get("plate_area")if self.area: self.area = np.array(list(map(int, self.area.split(",")))).reshape(-1, 1, 2).astype(np.int32)我们目前对于车型和车牌检测的参数配置是保持一致的,也可以配置为不同参数。3.5 三方依赖库本应用依赖scipy等工具包,ModelBox应用不需要手动安装三方依赖库,只需要配置在dependence\modelbox_requirements.txt,应用在编译时会自动安装。3.6 启动脚本执行应用在项目目录下执行.\bin\main.bat运行应用:.\bin\main.bat白线即配置的感兴趣区域,区域外/未过线车辆根据id赋色,区域内/已过线车辆的使用灰色框,可在输入输出配置中修改划区域任务类型与坐标点。总结AI寻车系统的搭建难点和挑战主要包括以下几个方面:数据采集和处理:需要收集大量的车辆数据,包括车型、颜色、车牌号码等信息,并对这些数据进行处理和分析,以便系统能够准确地识别和追踪车辆。图像识别和处理:需要使用先进的图像识别技术,对车辆的外观特征进行识别和分析,以便系统能够准确地识别车辆。实时性和准确性:需要保证系统能够实时地追踪车辆,并准确地识别车辆的位置和状态,以便及时采取措施。安全性和隐私保护:需要保护车主的隐私和车辆的安全,防止系统被黑客攻击或滥用。华为云ModelBox提供了一种快速、高效的模型部署方式,可以帮助开发者快速将训练好的模型部署到生产环境中,从而提高应用的响应速度和性能表现。同时,ModelBox还提供了多种部署方式和灵活的配置选项,可以满足不同场景下的需求。转载自:【愚公系列】华为云系列之基于ModelBox搭建的AI寻车系统
  • [技术干货] 一起了解ModelBox
    1.ModelBox是什么ModelBox是端边云统一的、高性能、高扩展、易用的AI推理开发框架,它可以帮助AI开发者快速完成从模型文件到AI推理应用的开发和上线工作,降低AI算法落地门槛,同时带来AI应用的高稳定性和极致性能。2.AI开发遇到的问题和解决方案一2.1 相关问题AI硬件主要有以下几种:GPU(图形处理器):GPU是一种高度并行的处理器,适合于处理大规模的数据并行计算,因此被广泛应用于深度学习等AI领域。FPGA(现场可编程门阵列):FPGA是一种可编程的硬件,可以根据需要重新配置其电路,因此适合于加速特定的计算任务,如卷积神经网络。ASIC(专用集成电路):ASIC是一种专门为某种特定应用而设计的芯片,可以提供高性能和低功耗,但是开发成本较高。CPU(中央处理器):CPU是一种通用的处理器,可以执行各种不同的计算任务,但是在处理大规模的数据并行计算时性能较差。TPU(张量处理器):TPU是一种专门为深度学习任务而设计的芯片,可以提供高性能和低功耗,但是只能用于特定的计算任务。AI 基础框架种类包括 TensorFlow、PyTorch、Keras、Caffe、MXNet 等。在如此多的AI硬件和基础框架会造成一系列问题:部署场景复杂,系统架构涉及端边云多种组合芯片、操作系统、推理框架纷繁多样2.2 解决方案ModelBox的特性(应用编排异构计算组件),它具有以下特性:支持多种异构计算组件,包括CPU、GPU、FPGA等。提供了灵活的应用编排能力,可以根据应用需求自由组合不同的计算组件。支持动态调度和资源管理,可以根据实际负载情况自动调整计算资源。具有高效的数据传输和通信能力,可以实现不同计算组件之间的数据交换和协同计算。总之,ModelBox是一种高性能、灵活、可扩展的应用编排异构计算组件,可以为各种应用提供强大的计算支持,缩短跨平台开发和部署成本,一次开发,端边云部署运行。3.AI开发遇到的问题和解决方案二3.1 相关问题AI应用性能优化确实是一个挑战,因为AI模型通常需要大量的计算资源和时间来训练和推理。但是,有许多技术可以用来优化AI应用的性能,例如使用更高效的算法、优化硬件和软件配置、使用分布式计算等。此外,还可以使用一些技术来减少模型的大小和复杂度,以提高性能。对于本案例中AI应用性能优化困难主要有:视频分析应用:多模型多模块,提高FPSHTTP服务:高并发,降低时延,提高吞吐量3.2 解决方案ModelBox的特性(高性能并发调度引擎):ModelBox是一个高性能并发调度引擎,它可以帮助开发者更高效地管理和调度任务,提高系统的并发能力和性能。它的特性包括:支持多种任务类型,支持任务优先级,支持任务依赖关系,支持任务超时控制,支持任务重试机制,支持任务状态监控和报告等。开发者无需掌握底层调度机制,也能保证应用优化效果。4.ModelBox的功能流程图:有向图,表达应用逻辑,控制ModelBox执行过程,采用GraphvizDOT语言进行表述功能单元:流程图中的顶点,应用的基本组成部分,ModelBox的执行单元,开发者主要开发的组件ModelBoxAI应用开发流程:流程图设计:定义业务流程,划分功能单元,理顺功能单元间的数据传递关系功能单元开发:采用框架已提供的通用功能单元,实现自己定义的业务功能单元运行与测试:使用图片、视频文件、实时视频流等测试应用5.ModelBox的其他特性预置视频处理、图像处理、HTTP服务等通用功能单元,缩短开发成本集成可视化编排服务,零代码体验AI应用开发6.ModelBox的应用场景华为云ModelBox的应用场景包括但不限于:机器学习、深度学习、自然语言处理、图像识别、智能推荐、数据分析等领域。它可以帮助企业快速构建和部署AI模型,提高数据的价值和利用率,实现智能化转型。
  • [技术干货] 用Python定制我的《本草纲目女孩》
    1.案例实现流程众所周知,视频是由一帧帧图像构成,Opencv处理视频图像信息的原理就是将视频转为一帧帧图像,处理完图像后再转换为视频。用Python实现案例流程如下:2.案例环境部署2.1 本机环境vs2022anaconda(已经包括opencv和PIL)python2.2 安装对应的anaconda包anaconda这是一个非常常用的python包集成管理工具,其中预安装了很多python库,使得我们不需要去手动安装各种的第三方库,我们知道自己取手动安装的过程中,很容易就会遇到一些报错,解决起来也非常的麻烦。anaconda官网:cid:link_1下载完软件包一路点击安装就行了,安装成功后会出现如下界面。查看是否安装成功命令:conda --version2.3 安装opencv-python进入anaconda控制台输入如下命令:3.案例实现代码本案例的实现过程主要分为以下几步:1. 导入数据2. 导入库函数3. 将视频转化为图像帧4. 对图片帧进行ASCII码的转换5. 将转换好的图片帧合成视频3.1 导入数据视频下载地址:cid:link_03.2 导入库函数#导入Python库import cv2from PIL import Image,ImageFont,ImageDrawimport osfrom cv2 import VideoWriter, VideoWriter_fourcc, imread, resize3.3 将视频转化为图像帧#将视频转换为图片存入目标文件夹def video_to_pic(vp): number = 0 # 判断载入的视频是否可以打开 if vp.isOpened(): #r:布尔型 (True 或者False),代表有没有读取到图片,frame:表示截取到的一帧的图片的数据,是个三维数组 r,frame = vp.read() #判断文件夹是否存在,不存在的话则新建文件夹 if not os.path.exists('cache_pic'): os.mkdir('cache_pic') os.chdir('cache_pic') else: r = False #遍历视频,并将每一帧图片写入文件夹 while r: number += 1 cv2.imwrite(str(number)+'.jpg',frame) r,frame = vp.read() print('\n由视频一共生成了{}张图片!'.format(number)) # 修改当前工作目录至主目录 os.chdir("..") return number3.4 对图片帧进行ASCII码的转换#将图片进行批量化处理def star_to_char(number, save_pic_path): #判断文件夹是否存在,不存在的话则新建文件夹 if not os.path.exists('cache_char'): os.mkdir('cache_char') # 生成目标图片文件的路径列表 img_path_list = [save_pic_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] task = 0 for image_path in img_path_list: # 获取图片的分辨率 img_width, img_height = Image.open(image_path).size task += 1 #处理图片,并显示处理进程 img_to_char(image_path, img_width, img_height, task) print('{}/{} is processed.'.format(task, number)) print('=======================') print('All pictures were processed!') print('=======================') return 0# 将图片转换为灰度图像后进行ascii_char中的ASCII值输出# 函数输入像素RGBA值,输出对应的字符码。其原理是将字符均匀地分布在整个灰度范围内,像素灰度值落在哪个区间就对应哪个字符码。def get_char(r, g, b, alpha=256): #ascii_char就是字符列表,用来将不同灰度的像素进行不同字符体替换的参照。 ascii_char = list("#RMNHQODBWGPZ*@$C&98?32I1>!:-;. ") #alpha在为0的时候便是完全透明的图片,所以返回空 if alpha == 0: return '' length = len(ascii_char) #转为灰度图 #RGBA是代表Red(红色)、Green(绿色)、Blue(蓝色)和Alpha的色彩空间,Alpha通道一般用作不透明度参数 #如果一个像素的alpha通道数值为0%,那它就是完全透明的,而数值为100%则意味着一个完全不透明的像素 gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b) # unit = (256.0 + 1) / len(ascii_char) unit = 256 / len(ascii_char) return ascii_char[int(gray / unit)]def img_to_char(image_path, raw_width, raw_height, task): width = int(raw_width / 6) height = int(raw_height / 15) # 以RGB模式打开 im = Image.open(image_path).convert('RGB') im = im.resize((width, height), Image.NEAREST) txt = '' color = [] #遍历图片的每个像素 for i in range(height): for j in range(width): pixel = im.getpixel((j, i)) # 将颜色加入进行索引 color.append((pixel[0], pixel[1], pixel[2])) if len(pixel) == 4: txt += get_char(pixel[0], pixel[1], pixel[2], pixel[3]) else: txt += get_char(pixel[0], pixel[1], pixel[2]) txt += '\n' color.append((255, 255, 255)) im_txt = Image.new("RGB", (raw_width, raw_height), (255, 255, 255)) dr = ImageDraw.Draw(im_txt) font = ImageFont.load_default().font x, y = 0, 0 font_w, font_h = font.getsize(txt[1]) font_h *= 1.37 # 调整字体大小 for i in range(len(txt)): if (txt[i] == '\n'): x += font_h y = -font_w dr.text((y, x), txt[i], fill=color[i]) y += font_w #存储处理后的图片至文件夹 os.chdir('cache_char') im_txt.save(str(task) + '.jpg') #直接进入新创建的文件夹将生成的图片直接存入文件夹中 os.chdir("..") return 03.5 将转换好的图片帧合成视频# 进度条显示def process_bar(percent, start_str='', end_str='', total_length=0): bar = ''.join("■ " * int(percent * total_length)) + '' bar = '\r' + start_str + bar.ljust(total_length) + ' {:0>4.1f}%|'.format(percent * 100) + end_str print(bar, end='', flush=True)#图片帧合成视频def jpg_to_video(char_image_path, FPS): # 设置视频编码器,这里使用MP42编码器 video_fourcc = VideoWriter_fourcc(*"MP42") # 生成目标字符图片文件的路径列表 char_img_path_list = [char_image_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] # 获取图片的分辨率 char_img_test = Image.open(char_img_path_list[1]).size if not os.path.exists('video'): os.mkdir('video') video_writter = VideoWriter('video/output.avi', video_fourcc, FPS, char_img_test) sum = len(char_img_path_list) count = 0 for image_path in char_img_path_list: img = cv2.imread(image_path) video_writter.write(img) end_str = '100%' count = count + 1 process_bar(count / sum, start_str='', end_str=end_str, total_length=15) video_writter.release() print('\n') print('=======================') print('The video is finished!') print('=======================')3.6 主函数if __name__ == "__main__": #初始视频路径 video_path = 'test_demo0510.mp4' #原始视频转为图片的图片保存路径 save_pic_path = 'cache_pic' #图片经处理后的图片保存路径 save_charpic_path = 'cache_char' # 读取视频 vp = cv2.VideoCapture(video_path) # 将视频转换为图片 并进行计数,返回总共生成了多少张图片 number = video_to_pic(vp) # 计算视频帧数 FPS = vp.get(cv2.CAP_PROP_FPS) # 将图像进行字符串处理后 star_to_char(number, save_pic_path) vp.release() # 将图片合成为视频 jpg_to_video(save_charpic_path, FPS)3.7 运行结果运行后一共生成了382张图片,和视频文件,保存在如下文件夹下。4.案例播放代码import cv2from IPython.display import clear_output, Image, displaydef show_video(video_path, show_text): video = cv2.VideoCapture(video_path) while True: try: clear_output(wait=True) # 读取视频 ret, frame = video.read() if not ret: break height, width, _ = frame.shape cv2.putText(frame, show_text, (0, 100), cv2.FONT_HERSHEY_TRIPLEX, 3.65, (255, 0, 0), 2) frame = cv2.resize(frame, (int(width / 2), int(height / 2))) _, ret = cv2.imencode('.jpg', frame) display(Image(data=ret)) except KeyboardInterrupt: video.release() #视频循环播放i=1while i>0: show_video('video/output.avi',str(i)) i=i+1转载原文链接:【云驻共创】华为云AI之用Python定制我的《本草纲目女孩》_基于pyqty+华为云案例-CSDN博客
  • [技术干货] ModelArts+AppCube带你识别101种西式美食【转】
    前言1.ModelArts是什么ModelArts是面向AI开发者的一站式开发平台,提供海量数据预处理及半自动化标注、大规模分布式训练、自动化模型生成及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期AI工作流。“一站式”是指AI开发的各个环节,包括数据处理、算法开发、模型训练、模型部署都可以在ModelArts上完成。从技术上看,ModelArts底层支持各种异构计算资源,开发者可以根据需要灵活选择使用,而不需要关心底层的技术。同时,ModelArts支持Tensorflow、PyTorch、MindSpore等主流开源的AI开发框架,也支持开发者使用自研的算法框架,匹配您的使用习惯。ModelArts的理念就是让AI开发变得更简单、更方便。面向不同经验的AI开发者,提供便捷易用的使用流程。例如,面向业务开发者,不需关注模型或编码,可使用自动学习流程快速构建AI应用;面向AI初学者,不需关注模型开发,使用预置算法构建AI应用;面向AI工程师,提供多种开发环境,多种操作流程和模式,方便开发者编码扩展,快速构建模型及应用。2.AppCube是什么应用魔方 AppCube是华为云为行业客户、合作伙伴、开发者量身打造的一款零代码和低代码应用开发平台,通过AppCube可轻松构建专业级应用,创新随心所欲,敏捷超乎想象。一、华为云系列之ModelArts+AppCube带你识别101种西式美食识别101种西式美食的业务流程图如下:1. AI Gallery 订阅模型及部署1、从AI Gallery 访问需要订阅的模型,本次以《自动识别101种西式美食》为例:cid:link_02、模型页面点击订阅按钮,勾选同意声明,点击“确定订阅”3、订阅成功后,如下图所示,点击前往控制台,云服务区域选择华北-北京四(后续涉及到云服务区域选择的均需选择此选项)4、确定后会自动跳转到 ModelArts 控制台的 AI 应用订阅界面,查看到我们订阅的这个模型,第一次需要等模型同步完成后才能继续使用,约1分钟左右5、同步完成后,点击右下角的部署按钮,选择在线服务6、进入在线服务配置页面,配置示例如下:名称:服务的名称,根据你自己偏好设置或保持默认计算节点规格:运行服务所用的计算资源(CPU/GPU),这里我们选择ModelArts提供的免费的算力规格,但注意一个账户下同时只能有一个免费规格的在线服务,如果您无法选择,说明您之前部署过免费规格的服务,需要删除之前的才能继续使用其它保持默认,勾选同意声明后,点击“下一步”按钮即可7、二次确认服务配置,点击“提交”即可进入模型部署状态。8、点击查看“服务详情”,进入服务部署详情页面,等待部署完成9、部署完成后如下所示,点击下方的“调用指南”tab页按钮,即可看到本服务的API接口注意图中的API接口地址和服务ID(后续会用到)至此 ModelArts 这边的服务部署已经完成,接下来我们去 AppCube 里进行 API 调用对接,在此之前,我们需要获得华为云账号的访问秘钥。2. 获取访问秘钥1、登录华为云账号后,进入控制台,点击右上角的用户名,在下拉菜单中选择“我的凭证”,进入我的凭证页面后,选择左侧的“访问秘钥”菜单,然后点击“新增访问秘钥”,按要求输入相关信息,有时候会有一个弹出框进行短信验证码认证,认证成功后即可下载秘钥信息。2、下载后是一个名为“credentials.csv”的文件,打开后会看到如下的类似信息,需要保存好,后续会用到。3. 使用示例安装包创建 AppCube 应用1、下载示例安装包下载地址:cid:link_22、进入运行环境AppCube网址:cid:link_33、点击应用开发-应用-导入项目4、选择下载的示例安装包5、上传成功后,返回后首页,可以看到刚刚导入的应用,默认名字“EI”4. 创建 ModelArts 连接器1、点击刚刚导入的“EI”项目后点击编辑编辑2、进入编辑页面后点击集成-连接器实例3、在“AI”分类下找到 ModelArts 选项,然后点击右侧的“+”号,新建一个连接器4、连接器设置界面如下所示,请确认相关参数输入正确,不可乱填(参考下方示例图):名称:对连接器的命名,根据自己的偏好设置,但请记住此名称,下一章操作会用到访问秘钥 ID:上一步“获取访问秘钥”步骤中下载的excel中Access Key Id字段对应 的值访问秘钥:上一步“获取访问秘钥” 步骤中下载的excel中Secret Access Key字段对 应的值区域:请选择“华北-北京四”项目ID:ModelArts 在线服务页面中的服务 ID (可在 ModelArts“总览”-“使用详情”-“在线服务”中点击对应的服务获取)5、保存成功后如下所示:6、点击上图中的“测试”按钮进行调用测试,看是否配置成功,参数选项如下:选择类型:图片的调用方式,本地上传和直接给图片 URL 都支持模型 Apig-Code:ModelArts 在线服务中 API 接口中 .apig 前面的部分,不包含 https://模型 ID:ModelArts 在线服务中的 API 接口中最后一个斜杠(/) 后面的部分URL:你要进行测试的图片地址,图片当前仅支持 jpg、png 格式填写完成后点击测试,如果成功即可获得 ModelArts 服务接口返回的JSON返回值,参考如下:5. 应用修改5.1 修改脚本需要点击上方的按钮进行禁用后才可编辑,编辑完成后记得保存并点击按钮进行启用将红色方框中的连接器信息替换为刚刚创建ModelArts 连接器名称如下图示例5.2 修改标准页面将代码中的 apigCode 和 modelId 对应的值替换模型 Apig-Code:ModelArts 在线服务中 API 接口中 .apig 前面的部分,不包含 https://模型 ID:ModelArts 在线服务中的 API 接口中最后一个斜杠(/) 后面的部分5.3 运行及测试在预览页面上传图片后,等待几秒,有数据返回即可总结AppCube低代码平台主要的优点有:无需任何代码,让您几分钟轻松搭建应用涵盖多种场景,行政办公、人力资源、运营协同、项目管理等内置丰富模板,疫情防控、行政办公、问卷调查、评选投票等高频模板ModelArts+AppCube可以实现AI应用嵌入应用中,赋予应用更完善的功能。对于这次体验华为ModelArts+AppCube所具备的功能是非常多的,不仅仅是前端页面的设计实现了低代码,后端逻辑和js脚本也可以在低代码使用,包括,定时任务等等功能,能够实现需求定制化开发,能够满足客户多元化需求应用。您也可以基于自身需求进行个性化定制,成为应用开发大师,快来解锁您的应用开发之旅吧!转载原文链接:http://t.csdnimg.cn/UtszV