Android Tensorflow IllegalArgumentException错误
我正在使用android studio和android版本的tensorflow进行图像识别。 它不是连续的跟踪和识别,只是对一幅图像的识别。 我已经有图形pb和标签txt文件,并设置所需的设置。 但有一个大问题。 关于图像,尺寸误差,我反复犯同样的错误。 这是错误日志和我的源代码Android Tensorflow IllegalArgumentException错误,android,tensorflow,Android,Tensorflow,我正在使用android studio和android版本的tensorflow进行图像识别。 它不是连续的跟踪和识别,只是对一幅图像的识别。 我已经有图形pb和标签txt文件,并设置所需的设置。 但有一个大问题。 关于图像,尺寸误差,我反复犯同样的错误。 这是错误日志和我的源代码 java.lang.IllegalArgumentException: input must be 4-dimensional[1,1,299,299,3]
java.lang.IllegalArgumentException: input must be 4-dimensional[1,1,299,299,3]
[[Node: ResizeBilinear = ResizeBilinear[T=DT_FLOAT, align_corners=false, _device="/job:localhost/replica:0/task:0/cpu:0"](ExpandDims, ResizeBilinear/size)]]
at org.tensorflow.Session.run(Native Method)
at org.tensorflow.Session.access$100(Session.java:48)
at org.tensorflow.Session$Runner.runHelper(Session.java:295)
at org.tensorflow.Session$Runner.run(Session.java:245)
at org.tensorflow.contrib.android.TensorFlowInferenceInterface.run(TensorFlowInferenceInterface.java:144)
at com.example.yuuuuu.tensorTest.TensorFlowImageClassifier.recognizeImage(TensorFlowImageClassifier.java:119)
at com.example.yuuuuu.tensorTest.MainActivity.runTensor(MainActivity.java:69)
at com.example.yuuuuu.tensorTest.MainActivity$1.onClick(MainActivity.java:42)
at android.view.View.performClick(View.java:6205)
at android.widget.TextView.performClick(TextView.java:11103)
at android.view.View$PerformClick.run(View.java:23653)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
我不知道问题出在哪里,第一行[1,1299299,3]。我认为两个299是ImageSize,一个1是ImageStd,但我不知道另一个1和3是什么。。。
我在tensorflow github中键入了与官方代码相同的代码,只是更改了一些部分。
这是主要的活动
public class MainActivity extends AppCompatActivity {
private static final String MODEL_FILE = "file:///android_asset/optimized_graph.pb";
private static final String LABEL_FILE = "file:///android_asset/output_labels.txt";
private static final String INPUT_NAME = "Cast";
private static final String OUTPUT_NAME = "final_result";
private static final int INPUT_SIZE = 299;
private static final int IMAGE_MEAN = 117;
private static final float IMAGE_STD = 1;
private Classifier classifier;
private TextView textView;
private ImageView img;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.textView);
button = (Button)findViewById(R.id.btn);
img = (ImageView)findViewById(R.id.img);
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
runTensor();
}
});
initTensor();
}
public void initTensor(){
classifier = TensorFlowImageClassifier.create(
getAssets(),
MODEL_FILE,
LABEL_FILE,
INPUT_SIZE,
IMAGE_MEAN,
IMAGE_STD,
INPUT_NAME,
OUTPUT_NAME
);
}
public void runTensor(){
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
bitmap = Bitmap.createScaledBitmap(bitmap, INPUT_SIZE, INPUT_SIZE, false);
img = (ImageView)findViewById(R.id.img);
img.setImageBitmap(bitmap);
final List<Classifier.Recognition> results = classifier.recognizeImage(bitmap);
textView.setText(results.toString());
}
protected void onDestroy(){
super.onDestroy();
classifier.close();
}
}
public类MainActivity扩展了AppCompatActivity{
私有静态最终字符串模型_文件=”file:///android_asset/optimized_graph.pb";
私有静态最终字符串标签_文件=”file:///android_asset/output_labels.txt";
私有静态最终字符串输入\u NAME=“Cast”;
私有静态最终字符串输出\u NAME=“最终结果”;
私有静态最终整数输入_SIZE=299;
私有静态最终整数图像_平均值=117;
专用静态最终浮点图像_STD=1;
私有分类器;
私有文本视图文本视图;
私有图像视图img;
私人按钮;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(textView)findViewById(R.id.textView);
按钮=(按钮)findViewById(R.id.btn);
img=(ImageView)findViewById(R.id.img);
setOnClickListener(新视图.OnClickListener(){
公共void onClick(视图v){
运行张量();
}
});
初始张量();
}
公共空间初始张量(){
分类器=TensorFlowImageClassifier.create(
getAssets(),
模型文件,
标签文件,
输入大小,
你的意思是,
图片(标准),
输入你的名字,
输出名称
);
}
公共空运行张量(){
位图Bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.test);
位图=位图。createScaledBitmap(位图,输入大小,输入大小,false);
img=(ImageView)findViewById(R.id.img);
设置图像位图(位图);
最终列表结果=分类器.识别图像(位图);
textView.setText(results.toString());
}
受保护的空onDestroy(){
super.ondestory();
close()分类器;
}
}
这是分类器,与官方代码相同
public interface Classifier {
public class Recognition{
private final String id;
private final String title;
private final Float confidence;
private RectF location;
public Recognition(
final String id, final String title, final Float confidence, final RectF location){
this.id = id;
this.title = title;
this.confidence = confidence;
this.location = location;
}
public String getId(){return id;}
public String getTitle(){return title;}
public Float getConfidence(){return confidence;}
public RectF getLocation(){return location;}
public void setLocation(RectF location){this.location = location;}
public String toString(){
String resultString = "";
if (id != null) {
resultString += "[" + id + "] ";
}
if (title != null) {
resultString += title + " ";
}
if (confidence != null) {
resultString += String.format("(%.1f%%) ", confidence * 100.0f);
}
if (location != null) {
resultString += location + " ";
}
return resultString.trim();
}
}
List<Recognition> recognizeImage(Bitmap bitmap);
void enableStatLogging(final boolean debug);
String getStatString();
void close();
}
公共接口分类器{
公众阶级认可{
私有最终字符串id;
私人最终字符串标题;
私人最终浮动信心;
私人RectF位置;
公众认可(
最终字符串id、最终字符串标题、最终浮点置信度、最终RectF位置){
this.id=id;
this.title=标题;
信心=信心;
这个位置=位置;
}
公共字符串getId(){return id;}
公共字符串getTitle(){return title;}
public Float getConfidence(){return confidence;}
public RectF getLocation(){return location;}
public void setLocation(RectF location){this.location=location;}
公共字符串toString(){
字符串resultString=“”;
如果(id!=null){
结果字符串+=“[”+id+“]”;
}
如果(标题!=null){
结果字符串+=标题+“”;
}
if(置信度!=null){
resultString+=String.format((.1f%%)”,置信度*100.0f);
}
如果(位置!=null){
结果字符串+=位置+“”;
}
返回resultString.trim();
}
}
列表识别图像(位图);
void enableStatLogging(最终布尔调试);
字符串getStatString();
无效关闭();
}
最后是TensorFlowImageClassifier,与official也一样
public class TensorFlowImageClassifier implements Classifier {
private static final String TAG = "TensorFlowImageClassifier";
private static final int MAX_RESULTS = 3;
private static final float THRESHOLD = 0.1f;
private String inputName;
private String outputName;
private int inputSize;
private int imageMean;
private float imageStd;
private Vector<String> labels = new Vector<String>();
private int[] intValues;
private float[] floatValues;
private float[] outputs;
private String[] outputNames;
private boolean logStats = false;
private TensorFlowInferenceInterface inferenceInterface;
private TensorFlowImageClassifier() {}
/*
assetManager : assets 로드하는데 사용
modelFilename : pb 파일
labelFilename : txt 파일
inputSize : 정사각형 길이, inputSize * inputSize
imageMean : image values 평균값
imageStd : image values 표준값?
inputName : image input 노드 레이블
outputName : output 노드 레이블
*/
public static Classifier create(
AssetManager assetManager, String modelFilename, String labelFilename, int inputSize, int imageMean, float imageStd, String inputName, String outputName){
TensorFlowImageClassifier c = new TensorFlowImageClassifier();
c.inputName = inputName;
c.outputName = outputName;
String actualFilename = labelFilename.split("file:///android_asset/")[1];
Log.d(TAG, "reading labels from : " + actualFilename);
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(assetManager.open(actualFilename)));
String line;
while((line = br.readLine()) != null){
c.labels.add(line);
}
br.close();
} catch (IOException e) {
throw new RuntimeException("failed reading labels" , e);
}
c.inferenceInterface = new TensorFlowInferenceInterface(assetManager, modelFilename);
final Operation operation = c.inferenceInterface.graphOperation(outputName);
final int numClasses = (int)operation.output(0).shape().size(1);
Log.d(TAG, "reading " + c.labels.size() + " labels, size of output layers : " + numClasses);
c.inputSize = inputSize;
c.imageMean = imageMean;
c.imageStd = imageStd;
c.outputNames = new String[]{outputName};
c.intValues = new int[inputSize * inputSize];
c.floatValues = new float[inputSize * inputSize * 3];
c.outputs = new float[numClasses];
return c;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public List<Recognition> recognizeImage(final Bitmap bitmap){
beginSection("recognizeImage");
beginSection("preprocessBitmap");
bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
for(int i = 0; i < intValues.length; i++){
final int val = intValues[i];
floatValues[i*3+0] = (((val >> 16) & 0xFF) - imageMean) / imageStd;
floatValues[i*3+1] = (((val >> 8) & 0xFF) - imageMean) / imageStd;
floatValues[i*3+2] = ((val & 0xFF) - imageMean) / imageStd;
}
endSection();
beginSection("feed");
inferenceInterface.feed(inputName, floatValues, 1, inputSize, inputSize, 3);
endSection();
beginSection("run");
inferenceInterface.run(outputNames, logStats);
endSection();
beginSection("fetch");
inferenceInterface.fetch(outputName, outputs);
endSection();
PriorityQueue<Recognition> pq = new PriorityQueue<Recognition>(
3,
new Comparator<Recognition>(){
public int compare(Recognition lhs, Recognition rhs){
return Float.compare(rhs.getConfidence(), lhs.getConfidence());
}
}
);
for(int i = 0; i < outputs.length; ++i){
if(outputs[i] > THRESHOLD){
pq.add(
new Recognition("" + i, labels.size() > i ? labels.get(i) : "unknown", outputs[i], null));
}
}
final ArrayList<Recognition> recognitions = new ArrayList<Recognition>();
int recognitionSize = Math.min(pq.size(), MAX_RESULTS);
for(int i = 0; i < recognitionSize; ++i){
recognitions.add(pq.poll());
}
endSection();
return recognitions;
}
public void enableStatLogging(boolean logStats){this.logStats = logStats;}
public String getStatString(){return inferenceInterface.getStatString();}
public void close(){inferenceInterface.close();}
}
公共类TensorFlowImageClassifier实现分类器{
私有静态最终字符串标记=“TensorFlowImageClassifier”;
私有静态最终int MAX_结果=3;
专用静态最终浮动阈值=0.1f;
私有字符串输入名;
私有字符串outputName;
私有int输入大小;
私人平均值;
私人浮动图像;
私有向量标签=新向量();
私有int[]int值;
私有浮动[]浮动值;
私有浮动[]输出;
私有字符串[]输出名称;
私有布尔logStats=false;
私有TensorFlow推断接口推断接口;
私有TensorFlowImageClassifier(){}
/*
资产管理器:资产로드하는데 사용
模型文件名:pb파일
labelFilename:txt파일
输入大小:정사각형 길이, inputSize*inputSize
imageMean:图像值평균값
imageStd:图像值표준값?
inputName:图像输入노드 레이블
outputName:output노드 레이블
*/
公共静态分类器创建(
AssetManager AssetManager,String modelFilename,String labelFilename,int inputSize,int imageMean,float imageStd,String inputName,String outputName){
TensorFlowImageClassifier c=新的TensorFlowImageClassifier();
c、 inputName=inputName;
c、 outputName=outputName;
字符串actualFilename=labelFilename.split(“file:///android_asset/")[1];
Log.d(标签,“从:+actualFilename读取标签”);
BufferedReader br=null;
试一试{
br=新的BufferedReader(新的InputStreamReader(assetManager.open(actualFilename));
弦线;
而((line=br.readLine())!=null){
c、 标签。添加(行);
}
br.close();
}捕获(IOE异常){
抛出新的RuntimeException(“读取标签失败”,e);
}
c、 推断接口=新的TensorFlow推断接口(assetManager,modelFilename);
最终操作=c.推理接口.graphOperation(outputName);
final int numclass=(int)operation.output(0.shape().size(1);
Log.d(标记,“读取”+c.labels.size()+“标签,输出层的大小:“+numclass”);
c、 inputSize=inputSize;
c、 伊玛