热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Lucene全文检索入门

博客地址:http://www.moonxy.com一、前言

博客地址:http://www.moonxy.com

一、前言

Lucene 是 apache 软件基金会的一个子项目,由 Doug Cutting 开发,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的库,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene 的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene 是一套用于全文检索和搜寻的开源程式库,由 Apache 软件基金会支持和提供。

Lucene 提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在 Java 开发环境里 Lucene 是一个成熟的免费开源工具。就其本身而言,Lucene 是当前以及最近几年最受欢迎的免费 Java 信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。

最开始 Lucene 只由 java 开发,供 java 程序调用,随着 python 越来越火,Lucene 官网也提供了 python 版本的 lucene 库,供 python 程序调用,即 PyLucene。

技术分享图片

 

二、下载 Lucene

2.1 下载

访问 Lucene 官网 http://lucene.apache.org/,可以看到 绿色和红色两个下载按钮,分别提供 Lucene 和 Solr 的下载。

技术分享图片

这里简要说明一下 Lucene 和 Solr,Lucene 是一个做全文检索的库,开发者可以按照自己的实际业务需求来使用,而 Solr 是一个基于 Lucene 的全文检索服务器。Solr 是在 Lucene 的基础上进行扩展,并且提供了更加丰富的查询语句,可扩展性和可配置性比 Lucene 更高。除此之外 Solr 还提供了一个完善的管理页面,是一个产品级的全文搜索引擎。

官网首页提供了最新版本的下载链接,如果需要下载使用历史版本,可以访问 http://archive.apache.org/dist/lucene/java/,可以下载 Lucene 所有的发行版本。此处下载 6.6.0 版本。

技术分享图片

2.2 添加依赖

将下载的 Lucene 包解压之后,找到如下的 jar 包,新建自己的工程,此处不使用 Maven,所以手动添加 jar 包到工程的 lib 目录下,如下:

技术分享图片

IKAnalyzer2012_u6.jar,此 jar 包在 IK 分词器项目中,是单独的一个工具包,需要额外在网上下载:IKAnalyzer2012_u6。IK 分词器采用了特有的 "正向迭代最细粒度切分算法",即从左到右的 正向最大(最长)和最小(最短)匹配,支持细粒度和智能分词两种切分模式,可将分词器扩展配置文件 IKAnalyzer.cfg.xml 放在项目的 class 根目录,并在其中配置扩展词典路径。当 IKAnalyzer6x()构造方法参数为空或者false时,是最细粒度分词,为true 时是智能分词。

lucene-analyzers-common-6.6.0.jar:lucene-6.6.0/common/

lucene-analyzers-smartcn-6.6.0.jar:lucene-6.6.0/smartcn/

lucene-core-6.6.0.jar:lucene-6.6.0/core/

lucene-highlighter-6.6.0.jar:lucene-6.6.0/highlighter/

lucene-memory-6.6.0.jar:lucene-6.6.0/memory/

lucene-queries-6.6.0.jar:lucene-6.6.0/queries/

lucene-queryparser-6.6.0.jar:lucene-6.6.0/queryparser/

2.3 Lucene 架构

首先是信息采集的过程,文件系统、数据库、万维网以及手工输入的文件都可以作为信息采集的对象,也是要搜索的文档的来源,采集万维网上的信息一般使用网络爬虫。完成信息采集之后到 Lucene 层面主要有两个任务:索引文档和搜索文档。

索引文档的过程完成由原始文档到倒排索引的构建过程;

搜索文档用以处理用户查询。然后当用户输入查询关键词,Lucene 完成文档搜索任务,经过分词、匹配、评分、排序等一系列过程之后返回用户想要的文档。

倒排索引(Inverted index),也常被称为反向索引,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射,它是文档检索系统中最常用的数据结构,包括词项所在的文章号、词项频率、词项位置等。

三、Lucene 索引详解

3.1 创建实体模型

创建新闻实体类模型

package tup.lucene.index;
/**
* 新闻实体类
*
@author moonxy
*
*/
public class News {
private int id;//新闻id
private String title;//新闻标题
private String content;//新闻内容
private int reply;//评论数 public News() {

}
public News(int id, String title, String content, int reply) {
super();
this.id = id;
this.title = title;
this.cOntent= content;
this.reply = reply;
}
// 省略 setter 和 getter 方法

}

3.2 创建索引

Lucene 索引文档需要依靠 IndexWriter 对象,创建 IndexWriter 需要两个参数:一个是 IndexWriterConfig 对象,该对象可以设置创建索引使用哪种分词器,另一个是索引的保存路径。IndexWriter 对象的 addDocument() 方法用于添加文档,该方法的参数为 Document 对象,IndexWriter 对象一次可以添加多个文档,最后调用 commit() 方法生成索引。

package tup.lucene.index;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import tup.lucene.ik.IKAnalyzer6x;
/**
* Lucene 创建索引
*
@author moonxy
*
*/
public class CreateIndex {
public static void main(String[] args) {
// 创建3个News对象
News news1 = new News();
news1.setId(
1);
news1.setTitle(
"安倍晋三本周会晤特朗普 将强调日本对美国益处");
news1.setContent(
"日本首相安倍晋三计划2月10日在华盛顿与美国总统特朗普举行会晤时提出加大日本在美国投资的设想");
news1.setReply(
672);

News news2
= new News();
news2.setId(
2);
news2.setTitle(
"北大迎4380名新生 农村学生700多人近年最多");
news2.setContent(
"昨天,北京大学迎来4380名来自全国各地及数十个国家的本科新生。其中,农村学生共700余名,为近年最多...");
news2.setReply(
995);
News news3
= new News();
news3.setId(
3);
news3.setTitle(
"特朗普宣誓(Donald Trump)就任美国第45任总统");
news3.setContent(
"当地时间1月20日,唐纳德·特朗普在美国国会宣誓就职,正式成为美国第45任总统。");
news3.setReply(
1872);

// 开始时间
Date start = new Date();
System.out.println(
"**********开始创建索引**********");
// 创建IK分词器
Analyzer analyzer = new IKAnalyzer6x();//使用IK最细粒度分词
IndexWriterConfig icw = new IndexWriterConfig(analyzer);
     // CREATE 表示先清空索引再重新创建
icw.setOpenMode(OpenMode.CREATE);
Directory dir
= null;
IndexWriter inWriter
= null;
// 存储索引的目录
Path indexPath = Paths.get("indexdir");
try {
if (!Files.isReadable(indexPath)) {
System.out.println(
"索引目录 ‘" + indexPath.toAbsolutePath() + "‘ 不存在或者不可读,请检查");
System.exit(
1);
}
dir
= FSDirectory.open(indexPath);
inWriter
= new IndexWriter(dir, icw);

// 设置新闻ID索引并存储
FieldType idType = new FieldType();
idType.setIndexOptions(IndexOptions.DOCS);
idType.setStored(
true);

// 设置新闻标题索引文档、词项频率、位移信息和偏移量,存储并词条化
FieldType titleType = new FieldType();
titleType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
titleType.setStored(
true);
titleType.setTokenized(
true);
FieldType contentType
= new FieldType();
contentType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
contentType.setStored(
true);
contentType.setTokenized(
true);
contentType.setStoreTermVectors(
true);
contentType.setStoreTermVectorPositions(
true);
contentType.setStoreTermVectorOffsets(
true);
Document doc1
= new Document();
doc1.add(
new Field("id", String.valueOf(news1.getId()), idType));
doc1.add(
new Field("title", news1.getTitle(), titleType));
doc1.add(
new Field("content", news1.getContent(), contentType));
doc1.add(
new IntPoint("reply", news1.getReply()));
doc1.add(
new StoredField("reply_display", news1.getReply()));

Document doc2
= new Document();
doc2.add(
new Field("id", String.valueOf(news2.getId()), idType));
doc2.add(
new Field("title", news2.getTitle(), titleType));
doc2.add(
new Field("content", news2.getContent(), contentType));
doc2.add(
new IntPoint("reply", news2.getReply()));
doc2.add(
new StoredField("reply_display", news2.getReply()));
Document doc3
= new Document();
doc3.add(
new Field("id", String.valueOf(news3.getId()), idType));
doc3.add(
new Field("title", news3.getTitle(), titleType));
doc3.add(
new Field("content", news3.getContent(), contentType));
doc3.add(
new IntPoint("reply", news3.getReply()));
doc3.add(
new StoredField("reply_display", news3.getReply()));
inWriter.addDocument(doc1);
inWriter.addDocument(doc2);
inWriter.addDocument(doc3);
inWriter.commit();
inWriter.close();
dir.close();
}
catch (IOException e) {
e.printStackTrace();
}
Date end
= new Date();
System.out.println(
"索引文档用时:" + (end.getTime() - start.getTime()) + " milliseconds");
System.out.println(
"**********索引创建完成**********");
}
}

执行之后,在控制台输出如下:

**********开始创建索引**********
加载扩展词典:dict/ext.dic
加载扩展停止词典:dict/stopword.dic
加载扩展停止词典:dict/ext_stopword.dic
索引文档用时:1064 milliseconds
**********索引创建完成**********

并且在项目中生成如下索引文件:

技术分享图片

3.3 Luke 查看索引

索引创建完成以后生成了如上的一批特殊格式的文件,如果直接用工具打开,会显示的都是乱码。可以使用索引查看工具 Luke 来查看。

Luke 是开源工具,代码托管在 GitHub 上,项目地址:https://github.com/DmitryKey/luke/releases,此处下载 luke 6.6.0,地址为 https://github.com/DmitryKey/luke/releases/download/luke-6.6.0/luke-6.6.0-luke-release.zip,如果在 Windows 中无法下载,可以在 Linux 中使用 wget 下载,命令为:wget https://github.com/DmitryKey/luke/releases/download/luke-6.6.0/luke-6.6.0-luke-release.zip。

下载后解压,进入 luke 目录,如果是在 Linux 平台,运行 luke.bat 即可启动软件,并在 Path 中输入 index 存储的目录,即可打开索引文件,显示出索引的具体内容。

技术分享图片

注意:对于不同版本的 Lucene,需要选择对应版本的 Luke,否则可能会出现不能正常解析的错误。

3.4 Lucene 查询详解

在 Lucene 中,处理用户输入的查询关键词其实就是构建 Query  对象的过程。Lucene 搜索文档需要先读入索引文件,实例化一个 IndexReader 对象,然后实例化出 IndexSearch 对象,IndexSearch 对象的 search() 方法完成搜索过程,Query 对象作为 search() 方法的对象。搜索结果保存在一个 TopDocs 类型的文档集合中,遍历 TopDocs 集合输出文档信息。

package tup.lucene.queries;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.queryparser.classic.QueryParser.Operator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import tup.lucene.ik.IKAnalyzer6x;
/**
* 单域搜索
*
@author moonxy
*
*/
public class QueryParseTest {
public static void main(String[] args) throws ParseException, IOException {
// 搜索单个字段
String field = "title";
// 搜索多个字段时使用数组
//String[] fields = { "title", "content" };

Path indexPath
= Paths.get("indexdir");
Directory dir
= FSDirectory.open(indexPath);
IndexReader reader
= DirectoryReader.open(dir);
IndexSearcher searcher
= new IndexSearcher(reader);
Analyzer analyzer
= new IKAnalyzer6x(false);//最细粒度分词
QueryParser parser = new QueryParser(field, analyzer);

// 多域搜索
//MultiFieldQueryParser multiParser = new MultiFieldQueryParser(fields, analyzer);

// 关键字同时成立使用 AND, 默认是 OR
parser.setDefaultOperator(Operator.AND);
// 查询语句
Query query = parser.parse("农村学生");//查询关键词
System.out.println("Query:" + query.toString());

// 返回前10条
TopDocs tds = searcher.search(query, 10);
for (ScoreDoc sd : tds.scoreDocs) {
// Explanation explanation = searcher.explain(query, sd.doc);
// System.out.println("explain:" + explanation + "
");

Document doc = searcher.doc(sd.doc);
System.out.println(
"DocID:" + sd.doc);
System.out.println(
"id:" + doc.get("id"));
System.out.println(
"title:" + doc.get("title"));
System.out.println(
"content:" + doc.get("content"));
System.out.println(
"文档评分:" + sd.score);
}
dir.close();
reader.close();
}
}

控制台输出如下:

加载扩展词典:dict/ext.dic
加载扩展停止词典:dict
/stopword.dic
加载扩展停止词典:dict
/ext_stopword.dic
Query:
+title:农村 +title:村学 +title:学生
DocID:
1
id:
2
title:北大迎4380名新生 农村学生700多人近年最多
content:昨天,北京大学迎来4380名来自全国各地及数十个国家的本科新生。其中,农村学生共700余名,为近年最多...
文档评分:
2.320528

注意,在结果中打印了 DocID 和 id,前者是文档的 ID,是 Lucene 为索引的每个文档标记,后者是文档自定义的 id 字段。

3.5 Lucene 查询高亮

高亮功能一直都是全文检索的一项非常优秀的模块,在一个标准的搜索引擎中,高亮的返回命中结果,几乎是必不可少的一项需求,因为通过高亮,可以在搜索界面上快速标记出用户的搜索关键字,从而减少了用户自己寻找想要的结果的时间,在一定程度上大大提高了用户的体验性和友好度。

Highlight 包含3个主要部分:

1)段划分器:Fragmenter

2)计分器:Score

3)格式化器:Formatter

package tup.lucene.highlfighter;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimplehtmlFormatter;
import org.apache.lucene.search.highlight.SimpleSpanFragmenter;
import org.apache.lucene.search.highlight.TokenSources;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import tup.lucene.ik.IKAnalyzer6x;
/**
* Lucene查询高亮
*
@author moonxy
*
*/
public class HighlighterTest {
public static void main(String[] args) throws IOException, InvalidTokenOffsetsException, ParseException {
String field
= "title";
Path indexPath
= Paths.get("indexdir");
Directory dir
= FSDirectory.open(indexPath);
IndexReader reader
= DirectoryReader.open(dir);
IndexSearcher searcher
= new IndexSearcher(reader);
Analyzer analyzer
= new IKAnalyzer6x();
QueryParser parser
= new QueryParser(field, analyzer);
Query query
= parser.parse("北大学生");
System.out.println(
"Query:" + query);
// 查询高亮
QueryScorer score = new QueryScorer(query, field);
SimpleHTMLFormatter fors
= new SimpleHTMLFormatter("", "");// 定制高亮标签
Highlighter highlighter = new Highlighter(fors, score);// 高亮分析器
// 返回前10条
TopDocs tds = searcher.search(query, 10);
for (ScoreDoc sd : tds.scoreDocs) {
// Explanation explanation = searcher.explain(query, sd.doc);
// System.out.println("explain:" + explanation + "
");

Document doc = searcher.doc(sd.doc);
System.out.println(
"id:" + doc.get("id"));
System.out.println(
"title:" + doc.get("title"));
Fragmenter fragment
= new SimpleSpanFragmenter(score);
highlighter.setTextFragmenter(fragment);
// TokenStream tokenStream = TokenSources.getAnyTokenStream(searcher.getIndexReader(), sd.doc, field, analyzer);// 获取tokenstream
// String str = highlighter.getBestFragment(tokenStream, doc.get(field));// 获取高亮的片段

String str
= highlighter.getBestFragment(analyzer, field, doc.get(field));// 获取高亮的片段
System.out.println("高亮的片段:" + str);
}
dir.close();
reader.close();
}
}

控制台输出如下:

加载扩展词典:dict/ext.dic
加载扩展停止词典:dict
/stopword.dic
加载扩展停止词典:dict
/ext_stopword.dic
Query:title:北大学生 title:北大 title:大学生 title:大学 title:学生
id:
2
title:北大迎4380名新生 农村学生700多人近年最多
高亮的片段:
北大迎4380名新生 农村学生700多人近年最多

四、Tika 文件内容提取

Apache Tika 是一个用于文件类型检测和文件内容提取的库,是 Apache 软件基金会的项目。Tika 可以检测操作 1000 种不同类型的文档,比如 PPT、PDF、DOC、XLS 等,所有的文本类型都可以通过一个简单的接口被解析,Tika 广泛应用于搜索引擎、内容分析、文本翻译等领域。

Tika 下载的官网地址:http://tika.apache.org/download.html,其历史版本下载地址为:http://archive.apache.org/dist/tika/,此处现在当前最新版 tika-app-1.18.jar

技术分享图片

下载下来之后为一个 jar 包,但 Tika 可作为 GUI 工具使用,在 CMD 中先进入下载目录,然后使用如下命令启动 Tika GUI:

java -jar tika-app-1.18.jar -g

java -jar 表示启动 jar 包,后面跟 jar 包的名字,-g(--gui) 参数表示以 GUI 的方式启动 Tika(Start the Apache Tika GUI),当然前提是已经配置好了 java 环境变量。

界面如下:

技术分享图片

可以点击 File 菜单中的 Open...来打开一个本地文件或者输入 URL 来打开远程文件,也可直接将本地文件拖入到 Tika,Tika 将会自动识别文件类型并显示文件信息。

默认显示文件的元数据信息,如下:

技术分享图片

点击 View 菜单,里面可以选择查看文件的具体内容,如选择其中的 Plain Text,显示如下:

技术分享图片

将该 jar 包放入项目 lib 中,调用相应的接口就可以提取不同文件的内容。



推荐阅读
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • IT方面的论坛太多了,有综合,有专业,有行业,在各个论坛里混了几年,体会颇深,以前是论坛哪里人多 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • ElasticSerach初探第一篇认识ES+环境搭建+简单MySQL数据同步+SpringBoot整合ES
    一、认识ElasticSearch是一个基于Lucene的开源搜索引擎,通过简单的RESTfulAPI来隐藏Lucene的复杂性。全文搜索,分析系统&# ... [详细]
  • android ... [详细]
  • 部署solr建立nutch索引
    2019独角兽企业重金招聘Python工程师标准接着上篇nutch1.4的部署应用,我们来部署一下solr,solr是对lucene进行了封装的企 ... [详细]
  • 本文介绍了腾讯最近开源的BERT推理模型TurboTransformers,该模型在推理速度上比PyTorch快1~4倍。TurboTransformers采用了分层设计的思想,通过简化问题和加速开发,实现了快速推理能力。同时,文章还探讨了PyTorch在中间层延迟和深度神经网络中存在的问题,并提出了合并计算的解决方案。 ... [详细]
author-avatar
温尧乔761975
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有